diff --git a/src/OpenIddict.Core/OpenIddictManager.cs b/src/OpenIddict.Core/OpenIddictManager.cs index 2f7a2ee2..fb5b33bb 100644 --- a/src/OpenIddict.Core/OpenIddictManager.cs +++ b/src/OpenIddict.Core/OpenIddictManager.cs @@ -46,6 +46,9 @@ namespace OpenIddict { } public virtual async Task FindClaimAsync(TUser user, string type) { + // Note: GetClaimsAsync will automatically throw an exception + // if the underlying store doesn't support custom claims. + return (from claim in await GetClaimsAsync(user) where string.Equals(claim.Type, type, StringComparison.Ordinal) select claim.Value).FirstOrDefault(); diff --git a/src/OpenIddict.Core/OpenIddictProvider.cs b/src/OpenIddict.Core/OpenIddictProvider.cs index 4c264e3e..96f5cf52 100644 --- a/src/OpenIddict.Core/OpenIddictProvider.cs +++ b/src/OpenIddict.Core/OpenIddictProvider.cs @@ -305,9 +305,12 @@ namespace OpenIddict { // don't include the "email" scope if the username corresponds to the registed email address. if (principal.HasClaim(OpenIdConnectConstants.Claims.Scope, OpenIdConnectConstants.Scopes.Profile)) { context.PreferredUsername = await manager.GetUserNameAsync(user); - context.FamilyName = await manager.FindClaimAsync(user, ClaimTypes.Surname); - context.GivenName = await manager.FindClaimAsync(user, ClaimTypes.GivenName); - context.BirthDate = await manager.FindClaimAsync(user, ClaimTypes.DateOfBirth); + + if (manager.SupportsUserClaim) { + context.FamilyName = await manager.FindClaimAsync(user, ClaimTypes.Surname); + context.GivenName = await manager.FindClaimAsync(user, ClaimTypes.GivenName); + context.BirthDate = await manager.FindClaimAsync(user, ClaimTypes.DateOfBirth); + } } // Only add the email address details if the "email" scope was present in the access token. @@ -420,6 +423,12 @@ namespace OpenIddict { identity.AddClaim(ClaimTypes.Email, email, destination: "id_token token"); } + if (manager.SupportsUserRole) { + foreach (var name in await manager.GetRolesAsync(user)) { + identity.AddClaim(identity.RoleClaimType, name, destination: "id_token token"); + } + } + context.Validate(new ClaimsPrincipal(identity)); } } diff --git a/src/OpenIddict.Mvc/OpenIddictController.cs b/src/OpenIddict.Mvc/OpenIddictController.cs index ab602314..aac65683 100644 --- a/src/OpenIddict.Mvc/OpenIddictController.cs +++ b/src/OpenIddict.Mvc/OpenIddictController.cs @@ -142,6 +142,12 @@ namespace OpenIddict { identity.AddClaim(ClaimTypes.Email, email, destination: "id_token token"); } + if (Manager.SupportsUserRole) { + foreach (var name in await Manager.GetRolesAsync(user)) { + identity.AddClaim(identity.RoleClaimType, name, destination: "id_token token"); + } + } + // Note: AspNet.Security.OpenIdConnect.Server automatically ensures an application // corresponds to the client_id specified in the authorization request using // IOpenIdConnectServerProvider.ValidateClientRedirectUri (see OpenIddictProvider.cs).