после двухдневных поисков, чтобы попытаться определить, где я иду не так, я согласился, что мне нужна помощь, чтобы указать мне правильное направление.
Я нахожусь на очень ранних этапах работы с сервером идентификации, все еще просто используя клиенты и области действия inMemory, просто чтобы понять, что происходит и как все это объединяется.
Я пытаюсь вернуть список пользовательских утверждений для моего углового приложения с сервера удостоверений, но мне не удается. Я попытался расширить IProfileService
, что успешно добавляет пользовательское утверждение, но удаляет другие утверждения, которые я определил в своем TestUser
С MyProfileService зарегистрирован
Без регистрации 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:
Дополнительные неудачные решения
Добавить поведение по умолчанию в 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
Добавить 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"
Определение пользовательских ресурсов идентификации ( документы ресурсов )
Я удалил 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"