Port SaveTokensAsClaims to the OpenID Connect middleware and automatically flow id_token_hint on logout requests

This commit is contained in:
Kévin Chalet 2015-09-18 01:28:23 +02:00 committed by Chris R
parent 1ef66c9c11
commit 742b96d18c
2 changed files with 82 additions and 0 deletions

View File

@ -89,6 +89,13 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
message.PostLogoutRedirectUri = Options.PostLogoutRedirectUri;
}
if (!string.IsNullOrEmpty(Options.SignInScheme))
{
var principal = await Context.Authentication.AuthenticateAsync(Options.SignInScheme);
message.IdTokenHint = principal?.FindFirst(OpenIdConnectParameterNames.IdToken)?.Value;
}
var redirectContext = new RedirectContext(Context, Options)
{
ProtocolMessage = message
@ -504,6 +511,12 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
}
ticket = authenticationValidatedContext.AuthenticationTicket;
if (Options.SaveTokensAsClaims)
{
// Persist the tokens extracted from the token response.
SaveTokens(ticket.Principal, tokenEndpointResponse.ProtocolMessage, saveRefreshToken: true);
}
if (Options.GetClaimsFromUserInfoEndpoint)
{
Logger.LogDebug(Resources.OIDCH_0040_Sending_Request_UIEndpoint);
@ -548,7 +561,27 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
{
return null;
}
message = authorizationCodeReceivedContext.ProtocolMessage;
ticket = authorizationCodeReceivedContext.AuthenticationTicket;
if (Options.SaveTokensAsClaims)
{
// TODO: call SaveTokens with the token response and set
// saveRefreshToken to true when the hybrid flow is fully implemented.
SaveTokens(ticket.Principal, message, saveRefreshToken: false);
}
}
// Implicit Flow
else
{
if (Options.SaveTokensAsClaims)
{
// Note: don't save the refresh token when it is extracted from the authorization
// response, since it's not a valid parameter when using the implicit flow.
// See http://openid.net/specs/openid-connect-core-1_0.html#Authentication
// and https://tools.ietf.org/html/rfc6749#section-4.2.2.
SaveTokens(ticket.Principal, message, saveRefreshToken: false);
}
}
return ticket;
@ -661,6 +694,47 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
return new AuthenticationTicket(new ClaimsPrincipal(identity), ticket.Properties, ticket.AuthenticationScheme);
}
/// <summary>
/// Save the tokens contained in the <see cref="OpenIdConnectMessage"/> in the <see cref="ClaimsPrincipal"/>.
/// </summary>
/// <param name="principal">The principal in which tokens are saved.</param>
/// <param name="message">The OpenID Connect response.</param>
/// <param name="saveRefreshToken">A <see cref="bool"/> indicating whether the refresh token should be stored.</param>
private void SaveTokens(ClaimsPrincipal principal, OpenIdConnectMessage message, bool saveRefreshToken)
{
var identity = (ClaimsIdentity) principal.Identity;
if (!string.IsNullOrEmpty(message.AccessToken))
{
identity.AddClaim(new Claim(OpenIdConnectParameterNames.AccessToken, message.AccessToken,
ClaimValueTypes.String, Options.ClaimsIssuer));
}
if (!string.IsNullOrEmpty(message.IdToken))
{
identity.AddClaim(new Claim(OpenIdConnectParameterNames.IdToken, message.IdToken,
ClaimValueTypes.String, Options.ClaimsIssuer));
}
if (saveRefreshToken && !string.IsNullOrEmpty(message.RefreshToken))
{
identity.AddClaim(new Claim(OpenIdConnectParameterNames.RefreshToken, message.RefreshToken,
ClaimValueTypes.String, Options.ClaimsIssuer));
}
if (!string.IsNullOrEmpty(message.TokenType))
{
identity.AddClaim(new Claim(OpenIdConnectParameterNames.TokenType, message.TokenType,
ClaimValueTypes.String, Options.ClaimsIssuer));
}
if (!string.IsNullOrEmpty(message.ExpiresIn))
{
identity.AddClaim(new Claim(OpenIdConnectParameterNames.ExpiresIn, message.ExpiresIn,
ClaimValueTypes.String, Options.ClaimsIssuer));
}
}
/// <summary>
/// Adds the nonce to <see cref="HttpResponse.Cookies"/>.
/// </summary>

View File

@ -7,6 +7,7 @@ using System.Diagnostics.CodeAnalysis;
using System.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Net.Http;
using System.Security.Claims;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.Framework.WebEncoders;
@ -226,6 +227,13 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
/// </summary>
public bool UseTokenLifetime { get; set; } = true;
/// <summary>
/// Defines whether access and refresh tokens should be stored in the
/// <see cref="ClaimsPrincipal"/> after a successful authentication.
/// You can set this property to <c>false</c> to reduce the size of the final authentication cookie.
/// </summary>
public bool SaveTokensAsClaims { get; set; } = true;
/// <summary>
/// Gets or sets the <see cref="IHtmlEncoder"/> used to sanitize HTML outputs.
/// </summary>