Идентификационный сервер настраивается в памяти IdentityResources - PullRequest
2 голосов
/ 19 марта 2019

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

Я нахожусь на очень ранних этапах работы с сервером идентификации, все еще просто используя клиенты и области действия inMemory, просто чтобы понять, что происходит и как все это объединяется.

Я пытаюсь вернуть список пользовательских утверждений для моего углового приложения с сервера удостоверений, но мне не удается. Я попытался расширить IProfileService, что успешно добавляет пользовательское утверждение, но удаляет другие утверждения, которые я определил в своем TestUser

С MyProfileService зарегистрирован

With MyProfileService

Без регистрации MyProfileService

Without MyProfileService

Startup.cs

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddIdentityServer()
                .AddDeveloperSigningCredential()
                .AddInMemoryApiResources(Resources.GetApiResources())
                .AddInMemoryIdentityResources(Resources.GetIdentityResources())
                .AddInMemoryClients(Clients.Get())
                .AddTestUsers(Users.Get())
                .AddDeveloperSigningCredential();

        //services.AddTransient<IProfileService, MyProfileService>();

        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole();

#if DEBUG
        app.UseDeveloperExceptionPage();
#endif

        app.UseIdentityServer();

        app.UseStaticFiles();

        app.UseMvcWithDefaultRoute();
    }

MyProfileService.cs

public class MyProfileService : IProfileService
{
    public MyProfileService()
    {
    }

    public Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        // Issue custom claim
        context.IssuedClaims.Add(new System.Security.Claims.Claim("TenantId", "123456"));
        return Task.CompletedTask;
    }

    public Task IsActiveAsync(IsActiveContext context)
    {
        context.IsActive = true;
        return Task.CompletedTask;
    }
}

Resources.cs

public static IEnumerable<IdentityResource> GetIdentityResources()
    {
        return new List<IdentityResource> {
            new IdentityResources.OpenId(),
            new IdentityResources.Profile(),
            new IdentityResources.Email(),
            new IdentityResource {
                Name = "role",
                UserClaims = new List<string> {"role"}
            },
            new IdentityResource
            {
                Name = "tenant.info",
                DisplayName = "Tenant Information",
                UserClaims = new List<string>
                {
                    "tenantid",
                    "subscriptionid"
                }
            }
        };
    }

    public static IEnumerable<ApiResource> GetApiResources()
    {
        return new List<ApiResource> {
            new ApiResource("api1", "api1")
        };
    }

Users.cs

    public static List<TestUser> Get()
    {
        return new List<TestUser> {
            new TestUser {
                SubjectId = "5BE86359-073C-434B-AD2D-A3932222DABE",
                Username = "scott",
                Password = "password",
                Claims = new List<Claim>
                {
                    new Claim("tenantid", "123456"),
                    new Claim(JwtClaimTypes.Name, "Scott xxxxx"),
                    new Claim(JwtClaimTypes.GivenName, "Scott"),
                    new Claim(JwtClaimTypes.FamilyName, "xxxxx"),
                    new Claim(JwtClaimTypes.Email, "Scottxxxxx@email.com"),
                    new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean),
                    new Claim(JwtClaimTypes.WebSite, "http://alice.com"),
                    new Claim(JwtClaimTypes.Address, @"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }", IdentityServer4.IdentityServerConstants.ClaimValueTypes.Json)
                }

            }
        };
    }

Clients.cs

public static IEnumerable<Client> Get()
    {
        return new List<Client> {
            new Client {
                ClientId = "angular_spa",
                ClientName = "Angular 4 Client",
                AllowedGrantTypes = GrantTypes.Code,
                RequirePkce = true,
                RequireClientSecret = false,
                AllowedScopes = new List<string> {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    "api1"
                },
                RedirectUris = new List<string> { "http://localhost:4200/admin/loggedin" },
                PostLogoutRedirectUris = new List<string> { "http://localhost:4200/admin/loggedout" },
                AllowedCorsOrigins = new List<string> { "http://localhost:4200" },
                AllowAccessTokensViaBrowser = true
            }
        };
    }

EDIT: Дополнительные неудачные решения

  1. Добавить поведение по умолчанию в MyProfileService (как следует из ответа Руарда ван Элбурга)

    public Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
    context.AddRequestedClaims(context.Subject.Claims);
    context.IssuedClaims.Add(new System.Security.Claims.Claim("tenantId", "123456"));
    }
    

    Результат в клиенте : показывает tenantId, но никаких других утверждений, которые я установил в своем TestUser

    , нет.
    profile:
    amr: ["pwd"]
    auth_time: 1553024858
    idp: "local"
    sid: "34f36d1c0056ad3d65d1671e339e73aa"
    sub: "5BE86359-073C-434B-AD2D-A3932222DABE"
    tenantId: "123456"
    __proto__: Object
    
  2. Добавить subject.claims к issedClaims

    public Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        context.IssuedClaims.Add(new System.Security.Claims.Claim("tenantId", "123456"));
        context.IssuedClaims.AddRange(context.Subject.Claims);
    }
    

    Результат в клиенте : показывает tenantId и имя (которое относится к имени пользователя), но никаких утверждений, которые я установил в своем TestUser

    profile:
    amr: ["pwd"]
    auth_time: 1553025311
    idp: "local"
    name: "scott"
    sid: "831a89053b54f3df7c9ca1bca92e1e10"
    sub: "5BE86359-073C-434B-AD2D-A3932222DABE"
    tenantId: "123456"
    
  3. Определение пользовательских ресурсов идентификации ( документы ресурсов )

    Я удалил MyProfileService и добавил

    public static IEnumerable<IdentityResource> GetIdentityResources()
    {
        var customProfile = new IdentityResource(
                                name: "custom.profile",
                                displayName: "Custom profile",
                                claimTypes: new[] {
                                    "name",
                                    "given_name",
                                    "family_name",
                                    "email",
                                    "email_verified",
                                    "website",
                                    "address",
                                    "status",
                                    "tenantid" });
    
    return new List<IdentityResource>
    {
        new IdentityResources.OpenId(),
        new IdentityResources.Profile(),
        customProfile
    };
    }
    

    Результат в клиенте Я не вижу все типы претензий

    profile:
    amr: ["pwd"]
    auth_time: 1553026892
    family_name: "FamilyName"
    given_name: "Scott givenName"
    idp: "local"
    name: "Scott name"
    sid: "47ae7f9b5240742e2b2b94a739bed5fa"
    sub: "5BE86359-073C-434B-AD2D-A3932222DABE"
    website: "http://scott.com"
    

1 Ответ

2 голосов
/ 19 марта 2019

Проблема в том, что вы удалили поведение по умолчанию.Поэтому вам нужно восстановить это, добавив следующую строку в службу профилей (которая присутствует в DefaultProfileService):

context.AddRequestedClaims(context.Subject.Claims);

Но нет необходимости реализовывать свой собственный IProfileService.В этом случае вам может быть достаточно, настроив область для клиента:

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

И запросив область в клиенте:

options.Scope.Add("tenant.info");

Этого должно быть достаточно, чтобы включить требование tenantId.

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