From 277a7149ad11a05a41a32c2ba282f19035fb3ee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Tue, 7 Mar 2017 01:55:18 +0100 Subject: [PATCH] Update the MVC sample to exclude the security stamp from the access/identity tokens --- .../Controllers/AuthorizationController.cs | 48 ++++++++++++++----- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/samples/Mvc.Server/Controllers/AuthorizationController.cs b/samples/Mvc.Server/Controllers/AuthorizationController.cs index cdc31650..fb83eb65 100644 --- a/samples/Mvc.Server/Controllers/AuthorizationController.cs +++ b/samples/Mvc.Server/Controllers/AuthorizationController.cs @@ -4,6 +4,7 @@ * the license and the contributors participating to this project. */ +using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; @@ -12,9 +13,11 @@ using AspNet.Security.OpenIdConnect.Primitives; using AspNet.Security.OpenIdConnect.Server; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http.Authentication; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; using Mvc.Server.Helpers; using Mvc.Server.Models; using Mvc.Server.ViewModels.Authorization; @@ -27,15 +30,18 @@ namespace Mvc.Server public class AuthorizationController : Controller { private readonly OpenIddictApplicationManager _applicationManager; + private readonly IOptions _identityOptions; private readonly SignInManager _signInManager; private readonly UserManager _userManager; public AuthorizationController( OpenIddictApplicationManager applicationManager, + IOptions identityOptions, SignInManager signInManager, UserManager userManager) { _applicationManager = applicationManager; + _identityOptions = identityOptions; _signInManager = signInManager; _userManager = userManager; } @@ -268,19 +274,6 @@ namespace Mvc.Server // will be used to create an id_token, a token or a code. var principal = await _signInManager.CreateUserPrincipalAsync(user); - // Note: by default, claims are NOT automatically included in the access and identity tokens. - // To allow OpenIddict to serialize them, you must attach them a destination, that specifies - // whether they should be included in access tokens, in identity tokens or in both. - - foreach (var claim in principal.Claims) - { - // In this sample, every claim is serialized in both the access and the identity tokens. - // In a real world application, you'd probably want to exclude confidential claims - // or apply a claims policy based on the scopes requested by the client application. - claim.SetDestinations(OpenIdConnectConstants.Destinations.AccessToken, - OpenIdConnectConstants.Destinations.IdentityToken); - } - // Create a new authentication ticket holding the user identity. var ticket = new AuthenticationTicket(principal, properties, OpenIdConnectServerDefaults.AuthenticationScheme); @@ -302,6 +295,35 @@ namespace Mvc.Server ticket.SetResources("resource_server"); + // Note: by default, claims are NOT automatically included in the access and identity tokens. + // To allow OpenIddict to serialize them, you must attach them a destination, that specifies + // whether they should be included in access tokens, in identity tokens or in both. + + foreach (var claim in ticket.Principal.Claims) + { + // Never include the security stamp in the access and identity tokens, as it's a secret value. + if (claim.Type == _identityOptions.Value.ClaimsIdentity.SecurityStampClaimType) + { + continue; + } + + var destinations = new List + { + OpenIdConnectConstants.Destinations.AccessToken + }; + + // Only add the iterated claim to the id_token if the corresponding scope was granted to the client application. + // The other claims will only be added to the access_token, which is encrypted when using the default format. + if ((claim.Type == OpenIdConnectConstants.Claims.Name && ticket.HasScope(OpenIdConnectConstants.Scopes.Profile)) || + (claim.Type == OpenIdConnectConstants.Claims.Email && ticket.HasScope(OpenIdConnectConstants.Scopes.Email)) || + (claim.Type == OpenIdConnectConstants.Claims.Role && ticket.HasScope(OpenIddictConstants.Claims.Roles))) + { + destinations.Add(OpenIdConnectConstants.Destinations.IdentityToken); + } + + claim.SetDestinations(destinations); + } + return ticket; } }