Токен доступа не содержит утверждения «sub» в токене доступа после вызова RequestClientCredentialsTokenAsync - PullRequest
0 голосов
/ 28 января 2019

Я настроил решение со следующими тремя активами:

  • Базовое приложение ASP.NET MVC
  • Базовое веб-API ASP.NET
  • хост IdentityServer4

В настоящее время аутентификация работает: если я пытаюсь получить доступ к защищенному ресурсу в приложении MVC, он перенаправляет на IdentityServer4, затем я могу войти в систему с моей учетной записью Facebook, пользователь подготовлен исгенерирован идентификатор субъекта, и я перенаправлен обратно в приложение MVC.Это работает правильно.

Я также могу вызвать функцию защищенного веб-API с сайта MVC.Однако в заявках, которые я получаю через веб-интерфейс API, я не получаю идентификатор субъекта.

Если я продолжу расследование, то увижу, что в моем приложении MVC я получаю токен доступа изВызов RequestClientCredentialsTokenAsync, но он содержит только:

{
  "nbf": 1548693531,
  "exp": 1548697131,
  "iss": "http://localhost:5000",
  "aud": [
    "http://localhost:5000/resources",
    "mgpApi"
  ],
  "client_id": "mgpPortal",
  "scope": [
    "mgpApi"
  ]
}

Мне бы хотелось, чтобы я также получал идентификатор субъекта в этом токене доступа , чтобы он также был в функции веб-APIчто я звоню.

Мой хост IdentityServer4 настроен на:

public void ConfigureServices(IServiceCollection services)
{
    var builder = services.AddIdentityServer()
            .AddInMemoryIdentityResources(Resources.GetIdentityResources())
            .AddInMemoryApiResources(Resources.GetApiResources())                
            .AddProfileService<ProfileService>()
            .AddInMemoryClients(Clients.Get());
}

... и я регистрирую клиента с:

new Client
{
    EnableLocalLogin = false,

    ClientId = "mgpPortal",
    ClientName = "MGP Portal Site",
    AllowedGrantTypes = GrantTypes.ImplicitAndClientCredentials,

    // where to redirect to after login
    RedirectUris = { "http://localhost:5002/signin-oidc" },

    // where to redirect to after logout
    PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },

    // secret for authentication
    ClientSecrets =
    {
        new Secret("secret".Sha256())
    },

    AllowedScopes = new List<string>
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        "mgpApi"
    },

    AllowOfflineAccess = true,
    AlwaysIncludeUserClaimsInIdToken = true,
    AlwaysSendClientClaims = true,
}

...и я также попытался в качестве теста добавить утверждения с помощью ProfileService, например:

public class ProfileService : IProfileService
{
    public Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        context.IssuedClaims.AddRange(context.Subject.Claims);
        context.IssuedClaims.Add(new Claim("sub", "test"));

        return Task.FromResult(0);
    }

    public Task IsActiveAsync(IsActiveContext context)
    {
        return Task.FromResult(0);
    }
}

Но это не имеет значения.

Мой клиент MVC настроен с:

public void ConfigureServices(IServiceCollection services)
{
    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

    services.AddAuthentication(options =>
    {
        options.DefaultScheme = "Cookies";
        options.DefaultChallengeScheme = "oidc";                 
    })
    .AddCookie("Cookies")
    .AddOpenIdConnect("oidc", options =>
    {                
        options.Authority = "http://localhost:5000";
        options.RequireHttpsMetadata = false;                
        options.ClientId = "mgpPortal";
        options.SaveTokens = true;                
    });           
}

Итак, что я должен добавить, чтобы получить идентификатор субъекта в маркере доступа?

Если требуется дополнительная информация, пожалуйста, дайте мне знать.Любая помощь приветствуется!

Ответы [ 2 ]

0 голосов
/ 02 июля 2019

Я был в похожей ситуации.После многих доказательств я обнаружил, что очень просто использовать тот же токен пользователя приложения MVC для доступа к другому приложению Web Api.Это объясняется здесь :

public async Task<IActionResult> CallApi()
{
    var accessToken = await HttpContext.GetTokenAsync("access_token");

    var client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
    ...
}

Здесь другая версия, использующая IdentityModel :

public async Task<IActionResult> CallApi()
{
  var accessToken = await HttpContext.GetTokenAsync("access_token");
  var apiClient = new HttpClient();
  client.SetBearerToken(accessToken); 
  ....
  await client.PutAsync(url, json);   

Надеюсь, что это может помочь ...

0 голосов
/ 28 января 2019

Вы используете неправильный поток, используйте hybrid поток.В client credentials нет понятия субъекта пользователя, следовательно, проблема, с которой вы столкнулись.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...