Не получается получение ролей с помощью сервера SSO Identity Framework 6.
Я пытался создать сервер входа в систему для использования в качестве сервера единого входа для нескольких приложений, но я не могу получить роли на своей клиентской стороне приложения. Когда я проверяю роли в User.Claims, там ничего нет, и [Authorize(roles = "Admin")], похоже, тоже не работает.
Мой текущий код:
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie(options =>
{
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
options.SlidingExpiration = true;
})
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = "https://localhost:5001";
options.ClientId = "CRMERPClient";
options.ClientSecret = "secret";
options.MapInboundClaims = false;
options.SaveTokens = true;
options.RequireHttpsMetadata = true;
options.GetClaimsFromUserInfoEndpoint = true;
// code flow + PKCE (PKCE is turned on by default)
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Add("crm");
options.Scope.Add("erp");
options.TokenValidationParameters.NameClaimType = "name";
options.TokenValidationParameters.RoleClaimType = "role";
options.ClaimActions.MapJsonKey("role", "role");
});
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(120);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
^ Моя клиентская программа.cs
builder.Services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
options.EmitStaticAudienceClaim = true;
})
.AddInMemoryIdentityResources(Config.IdentityResources)
.AddInMemoryApiResources(Config.ApiResources)
.AddInMemoryApiScopes(Config.ApiScopes)
.AddInMemoryClients(Config.Clients)
.AddTestUsers(TestUsers.Users)
.AddServerSideSessions()
.AddServerSideSessionStore<CustomServerSessionStore>()
.AddDeveloperSigningCredential().AddProfileService<ProfileService>();
builder.Services.AddTransient<IProfileService, ProfileService>();
^ Моя серверная программа.cs
public static IEnumerable<IdentityResource> IdentityResources =>
new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
public static IEnumerable<ApiScope> ApiScopes =>
new List<ApiScope>
{
new ApiScope("crm", "CRM"),
new ApiScope("erp", "ERP"),
new ApiScope("dms", "DMS")
};
public static IEnumerable<ApiResource> ApiResources =>
new List<ApiResource>
{
new ApiResource("crm")
{
Scopes = { "crm", "roles"}
},
new ApiResource("erp")
{
Scopes = { "erp", "roles"}
},
new ApiResource("dms")
{
Scopes = { "dms", "roles"}
}
};
public static IEnumerable<Client> Clients =>
new List<Client>
{
new Client
{
ClientId = "CRMERPClient",
AllowedGrantTypes = GrantTypes.Code,
// where to redirect after login
RedirectUris = { "https://localhost:7218/signin-oidc" },
// where to redirect after logout
PostLogoutRedirectUris = { "https://localhost:7218/signout-callback-oidc" },
ClientSecrets =
{
new Secret("secret".Sha256())
},
//https://docs.duendesoftware.com/identityserver/v6/quickstarts/1_client_credentials/
AllowedScopes = { "crm", "erp",
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
JwtClaimTypes.Role
},
},
new Client
{
ClientId = "DocumentManagementSystem",
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedGrantTypes = GrantTypes.Code,
RedirectUris = { "https://localhost:7218/signin-oidc" },
PostLogoutRedirectUris = { "https://localhost:7218/signout-callback-oidc" },
AllowOfflineAccess = true,
AllowedScopes = { "openid", "profile", "dms", "roles" }
}
};
^ Моя конфигурация сервера идентификации.
public class ProfileService : IProfileService
{
public ProfileService() { }
public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var roleClaims = context.Subject.FindAll(JwtClaimTypes.Role);
context.IssuedClaims.AddRange(roleClaims);
return Task.CompletedTask;
}
public Task IsActiveAsync(IsActiveContext context)
{
return Task.CompletedTask;
}
}
^И мой профиль Сервис
Я что-то упускаю? Я пытался решить эту проблему, следуя многочисленным руководствам и просматривая stackoverflow, но было трудно найти ответы для сервера идентификации 6 вместо сервера идентификации 4.
Спасибо вам за помощь!