From 7a2afc1515c4de67ce1c1b52c3a2f9c3c608ac06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Tue, 2 Feb 2016 02:13:09 +0100 Subject: [PATCH] Introduce a new "roles" scope and update the userinfo endpoint to expose user roles --- samples/Mvc.Client/Startup.cs | 1 + src/OpenIddict.Core/OpenIddictConstants.cs | 8 ++++++++ src/OpenIddict.Core/OpenIddictManager.cs | 2 +- src/OpenIddict.Core/OpenIddictProvider.cs | 15 ++++++++++++--- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/samples/Mvc.Client/Startup.cs b/samples/Mvc.Client/Startup.cs index dd1ffaa5..9e9abb67 100644 --- a/samples/Mvc.Client/Startup.cs +++ b/samples/Mvc.Client/Startup.cs @@ -71,6 +71,7 @@ namespace Mvc.Client { options.Authority = "http://localhost:54540/"; options.Scope.Add("email"); + options.Scope.Add("roles"); }); diff --git a/src/OpenIddict.Core/OpenIddictConstants.cs b/src/OpenIddict.Core/OpenIddictConstants.cs index eed6c08d..9f9f477b 100644 --- a/src/OpenIddict.Core/OpenIddictConstants.cs +++ b/src/OpenIddict.Core/OpenIddictConstants.cs @@ -4,5 +4,13 @@ public const string Confidential = "confidential"; public const string Public = "public"; } + + public static class Claims { + public const string Roles = "roles"; + } + + public static class Scopes { + public const string Roles = "roles"; + } } } diff --git a/src/OpenIddict.Core/OpenIddictManager.cs b/src/OpenIddict.Core/OpenIddictManager.cs index 0f984a10..04dc3c2c 100644 --- a/src/OpenIddict.Core/OpenIddictManager.cs +++ b/src/OpenIddict.Core/OpenIddictManager.cs @@ -84,7 +84,7 @@ namespace OpenIddict { identity.AddClaim(ClaimTypes.Email, email, destination: "id_token token"); } - if (SupportsUserRole) { + if (SupportsUserRole && scopes.Contains(OpenIddictConstants.Scopes.Roles)) { foreach (var role in await GetRolesAsync(user)) { identity.AddClaim(identity.RoleClaimType, role, destination: "id_token token"); } diff --git a/src/OpenIddict.Core/OpenIddictProvider.cs b/src/OpenIddict.Core/OpenIddictProvider.cs index bcbfc5f7..3ad2c5dc 100644 --- a/src/OpenIddict.Core/OpenIddictProvider.cs +++ b/src/OpenIddict.Core/OpenIddictProvider.cs @@ -11,6 +11,7 @@ using AspNet.Security.OpenIdConnect.Extensions; using AspNet.Security.OpenIdConnect.Server; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Internal; +using Newtonsoft.Json.Linq; namespace OpenIddict { public partial class OpenIddictProvider : OpenIdConnectServerProvider where TUser : class where TApplication : class { @@ -50,7 +51,7 @@ namespace OpenIddict { // Note: filtering the username is not needed at this stage as OpenIddictController.Accept // and OpenIddictProvider.GrantResourceOwnerCredentials are expected to reject requests that // don't include the "email" scope if the username corresponds to the registed email address. - if (principal.HasClaim(OpenIdConnectConstants.Claims.Scope, OpenIdConnectConstants.Scopes.Profile)) { + if (context.AuthenticationTicket.HasScope(OpenIdConnectConstants.Scopes.Profile)) { context.PreferredUsername = await manager.GetUserNameAsync(user); if (manager.SupportsUserClaim) { @@ -61,7 +62,7 @@ namespace OpenIddict { } // Only add the email address details if the "email" scope was present in the access token. - if (principal.HasClaim(OpenIdConnectConstants.Claims.Scope, OpenIdConnectConstants.Scopes.Email)) { + if (context.AuthenticationTicket.HasScope(OpenIdConnectConstants.Scopes.Email)) { context.Email = await manager.GetEmailAsync(user); // Only add the "email_verified" claim @@ -72,7 +73,7 @@ namespace OpenIddict { }; // Only add the phone number details if the "phone" scope was present in the access token. - if (principal.HasClaim(OpenIdConnectConstants.Claims.Scope, OpenIdConnectConstants.Scopes.Phone)) { + if (context.AuthenticationTicket.HasScope(OpenIdConnectConstants.Scopes.Phone)) { context.PhoneNumber = await manager.GetPhoneNumberAsync(user); // Only add the "phone_number_verified" @@ -81,6 +82,14 @@ namespace OpenIddict { context.PhoneNumberVerified = await manager.IsPhoneNumberConfirmedAsync(user); } } + + // Only add the roles list if the "roles" scope was present in the access token. + if (manager.SupportsUserRole && context.AuthenticationTicket.HasScope(OpenIddictConstants.Scopes.Roles)) { + var roles = await manager.GetRolesAsync(user); + if (roles.Count != 0) { + context.Claims[OpenIddictConstants.Claims.Roles] = JArray.FromObject(roles); + } + } } } } \ No newline at end of file