#372 Flow mutable event state.

#358 Add a UserInformationReceived event.
#327 Add AuthenticationCompleted event.
#340 Split the Redirect event for Authentication and SignOut.
Rename OnAuthorizationCodeRedeemed to OnTokenResponseReceived.
Move IdTokenReceived to AuthorizationResponseReceived.
Rename IdTokenValidated to AuthenticationValidated.
This commit is contained in:
Chris R 2015-09-16 14:31:36 -07:00
parent 92d5e4ce77
commit 1c0768fb71
17 changed files with 337 additions and 627 deletions

View File

@ -0,0 +1,15 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Http;
namespace Microsoft.AspNet.Authentication.OpenIdConnect
{
public class AuthenticationCompletedContext : BaseControlContext<OpenIdConnectOptions>
{
public AuthenticationCompletedContext(HttpContext context, OpenIdConnectOptions options)
: base(context, options)
{
}
}
}

View File

@ -6,15 +6,15 @@ using Microsoft.IdentityModel.Protocols.OpenIdConnect;
namespace Microsoft.AspNet.Authentication.OpenIdConnect namespace Microsoft.AspNet.Authentication.OpenIdConnect
{ {
public class SecurityTokenReceivedContext : BaseControlContext<OpenIdConnectOptions> public class AuthenticationValidatedContext : BaseControlContext<OpenIdConnectOptions>
{ {
public SecurityTokenReceivedContext(HttpContext context, OpenIdConnectOptions options) public AuthenticationValidatedContext(HttpContext context, OpenIdConnectOptions options)
: base(context, options) : base(context, options)
{ {
} }
public string SecurityToken { get; set; }
public OpenIdConnectMessage ProtocolMessage { get; set; } public OpenIdConnectMessage ProtocolMessage { get; set; }
public OpenIdConnectTokenEndpointResponse TokenEndpointResponse { get; set; }
} }
} }

View File

@ -2,17 +2,20 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.IdentityModel.Protocols.OpenIdConnect;
namespace Microsoft.AspNet.Authentication.OpenIdConnect namespace Microsoft.AspNet.Authentication.OpenIdConnect
{ {
public class SecurityTokenValidatedContext : BaseControlContext<OpenIdConnectOptions> public class AuthorizationResponseReceivedContext : BaseControlContext<OpenIdConnectOptions>
{ {
public SecurityTokenValidatedContext(HttpContext context, OpenIdConnectOptions options) public AuthorizationResponseReceivedContext(HttpContext context, OpenIdConnectOptions options)
: base(context, options) : base(context, options)
{ {
} }
public OpenIdConnectMessage ProtocolMessage { get; set; } public OpenIdConnectMessage ProtocolMessage { get; set; }
public AuthenticationProperties Properties { get; set; }
} }
} }

View File

@ -10,20 +10,30 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
/// </summary> /// </summary>
public interface IOpenIdConnectEvents public interface IOpenIdConnectEvents
{ {
/// <summary>
/// Invoked when the authentication process completes.
/// </summary>
Task AuthenticationCompleted(AuthenticationCompletedContext context);
/// <summary> /// <summary>
/// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed. /// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed.
/// </summary> /// </summary>
Task AuthenticationFailed(AuthenticationFailedContext context); Task AuthenticationFailed(AuthenticationFailedContext context);
/// <summary>
/// Invoked after the id token has passed validation and a ClaimsIdentity has been generated.
/// </summary>
Task AuthenticationValidated(AuthenticationValidatedContext context);
/// <summary> /// <summary>
/// Invoked after security token validation if an authorization code is present in the protocol message. /// Invoked after security token validation if an authorization code is present in the protocol message.
/// </summary> /// </summary>
Task AuthorizationCodeReceived(AuthorizationCodeReceivedContext context); Task AuthorizationCodeReceived(AuthorizationCodeReceivedContext context);
/// <summary> /// <summary>
/// Invoked after "authorization code" is redeemed for tokens at the token endpoint. /// Invoked when an authorization response is received.
/// </summary> /// </summary>
Task AuthorizationCodeRedeemed(AuthorizationCodeRedeemedContext context); Task AuthorizationResponseReceived(AuthorizationResponseReceivedContext context);
/// <summary> /// <summary>
/// Invoked when a protocol message is first received. /// Invoked when a protocol message is first received.
@ -31,18 +41,23 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
Task MessageReceived(MessageReceivedContext context); Task MessageReceived(MessageReceivedContext context);
/// <summary> /// <summary>
/// Invoked to manipulate redirects to the identity provider for SignIn, SignOut, or Challenge. /// Invoked before redirecting to the identity provider to authenticate.
/// </summary> /// </summary>
Task RedirectToIdentityProvider(RedirectToIdentityProviderContext context); Task RedirectToAuthenticationEndpoint(RedirectContext context);
/// <summary> /// <summary>
/// Invoked with the security token that has been extracted from the protocol message. /// Invoked before redirecting to the identity provider to sign out.
/// </summary> /// </summary>
Task SecurityTokenReceived(SecurityTokenReceivedContext context); Task RedirectToEndSessionEndpoint(RedirectContext context);
/// <summary> /// <summary>
/// Invoked after the security token has passed validation and a ClaimsIdentity has been generated. /// Invoked after "authorization code" is redeemed for tokens at the token endpoint.
/// </summary> /// </summary>
Task SecurityTokenValidated(SecurityTokenValidatedContext context); Task TokenResponseReceived(TokenResponseReceivedContext context);
/// <summary>
/// Invoked when user information is retrieved from the UserInfoEndpoint.
/// </summary>
Task UserInformationReceived(UserInformationReceivedContext context);
} }
} }

View File

@ -11,20 +11,30 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
/// </summary> /// </summary>
public class OpenIdConnectEvents : IOpenIdConnectEvents public class OpenIdConnectEvents : IOpenIdConnectEvents
{ {
/// <summary>
/// Invoked when the authentication process completes.
/// </summary>
public Func<AuthenticationCompletedContext, Task> OnAuthenticationCompleted { get; set; } = context => Task.FromResult(0);
/// <summary> /// <summary>
/// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed. /// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed.
/// </summary> /// </summary>
public Func<AuthenticationFailedContext, Task> OnAuthenticationFailed { get; set; } = context => Task.FromResult(0); public Func<AuthenticationFailedContext, Task> OnAuthenticationFailed { get; set; } = context => Task.FromResult(0);
/// <summary>
/// Invoked after the id token has passed validation and a ClaimsIdentity has been generated.
/// </summary>
public Func<AuthenticationValidatedContext, Task> OnAuthenticationValidated { get; set; } = context => Task.FromResult(0);
/// <summary> /// <summary>
/// Invoked after security token validation if an authorization code is present in the protocol message. /// Invoked after security token validation if an authorization code is present in the protocol message.
/// </summary> /// </summary>
public Func<AuthorizationCodeReceivedContext, Task> OnAuthorizationCodeReceived { get; set; } = context => Task.FromResult(0); public Func<AuthorizationCodeReceivedContext, Task> OnAuthorizationCodeReceived { get; set; } = context => Task.FromResult(0);
/// <summary> /// <summary>
/// Invoked after "authorization code" is redeemed for tokens at the token endpoint. /// Invoked when an authorization response is received.
/// </summary> /// </summary>
public Func<AuthorizationCodeRedeemedContext, Task> OnAuthorizationCodeRedeemed { get; set; } = context => Task.FromResult(0); public Func<AuthorizationResponseReceivedContext, Task> OnAuthorizationResponseReceived { get; set; } = context => Task.FromResult(0);
/// <summary> /// <summary>
/// Invoked when a protocol message is first received. /// Invoked when a protocol message is first received.
@ -32,32 +42,43 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
public Func<MessageReceivedContext, Task> OnMessageReceived { get; set; } = context => Task.FromResult(0); public Func<MessageReceivedContext, Task> OnMessageReceived { get; set; } = context => Task.FromResult(0);
/// <summary> /// <summary>
/// Invoked to manipulate redirects to the identity provider for SignIn, SignOut, or Challenge. /// Invoked before redirecting to the identity provider to authenticate.
/// </summary> /// </summary>
public Func<RedirectToIdentityProviderContext, Task> OnRedirectToIdentityProvider { get; set; } = context => Task.FromResult(0); public Func<RedirectContext, Task> OnRedirectToAuthenticationEndpoint { get; set; } = context => Task.FromResult(0);
/// <summary> /// <summary>
/// Invoked with the security token that has been extracted from the protocol message. /// Invoked before redirecting to the identity provider to sign out.
/// </summary> /// </summary>
public Func<SecurityTokenReceivedContext, Task> OnSecurityTokenReceived { get; set; } = context => Task.FromResult(0); public Func<RedirectContext, Task> OnRedirectToEndSessionEndpoint { get; set; } = context => Task.FromResult(0);
/// <summary> /// <summary>
/// Invoked after the security token has passed validation and a ClaimsIdentity has been generated. /// Invoked after "authorization code" is redeemed for tokens at the token endpoint.
/// </summary> /// </summary>
public Func<SecurityTokenValidatedContext, Task> OnSecurityTokenValidated { get; set; } = context => Task.FromResult(0); public Func<TokenResponseReceivedContext, Task> OnTokenResponseReceived { get; set; } = context => Task.FromResult(0);
/// <summary>
/// Invoked when user information is retrieved from the UserInfoEndpoint.
/// </summary>
public Func<UserInformationReceivedContext, Task> OnUserInformationReceived { get; set; } = context => Task.FromResult(0);
public virtual Task AuthenticationCompleted(AuthenticationCompletedContext context) => OnAuthenticationCompleted(context);
public virtual Task AuthenticationFailed(AuthenticationFailedContext context) => OnAuthenticationFailed(context); public virtual Task AuthenticationFailed(AuthenticationFailedContext context) => OnAuthenticationFailed(context);
public virtual Task AuthenticationValidated(AuthenticationValidatedContext context) => OnAuthenticationValidated(context);
public virtual Task AuthorizationCodeReceived(AuthorizationCodeReceivedContext context) => OnAuthorizationCodeReceived(context); public virtual Task AuthorizationCodeReceived(AuthorizationCodeReceivedContext context) => OnAuthorizationCodeReceived(context);
public virtual Task AuthorizationCodeRedeemed(AuthorizationCodeRedeemedContext context) => OnAuthorizationCodeRedeemed(context); public virtual Task AuthorizationResponseReceived(AuthorizationResponseReceivedContext context) => OnAuthorizationResponseReceived(context);
public virtual Task MessageReceived(MessageReceivedContext context) => OnMessageReceived(context); public virtual Task MessageReceived(MessageReceivedContext context) => OnMessageReceived(context);
public virtual Task RedirectToIdentityProvider(RedirectToIdentityProviderContext context) => OnRedirectToIdentityProvider(context); public virtual Task RedirectToAuthenticationEndpoint(RedirectContext context) => OnRedirectToAuthenticationEndpoint(context);
public virtual Task SecurityTokenReceived(SecurityTokenReceivedContext context) => OnSecurityTokenReceived(context); public virtual Task RedirectToEndSessionEndpoint(RedirectContext context) => OnRedirectToEndSessionEndpoint(context);
public virtual Task SecurityTokenValidated(SecurityTokenValidatedContext context) => OnSecurityTokenValidated(context); public virtual Task TokenResponseReceived(TokenResponseReceivedContext context) => OnTokenResponseReceived(context);
public virtual Task UserInformationReceived(UserInformationReceivedContext context) => OnUserInformationReceived(context);
} }
} }

View File

@ -0,0 +1,25 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Http;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
namespace Microsoft.AspNet.Authentication.OpenIdConnect
{
/// <summary>
/// When a user configures the <see cref="OpenIdConnectMiddleware"/> to be notified prior to redirecting to an IdentityProvider
/// an instance of <see cref="RedirectContext"/> is passed to the 'RedirectToAuthenticationEndpoint' or 'RedirectToEndSessionEndpoint' events.
/// </summary>
public class RedirectContext : BaseControlContext<OpenIdConnectOptions>
{
public RedirectContext(HttpContext context, OpenIdConnectOptions options)
: base(context, options)
{
}
/// <summary>
/// Gets or sets the <see cref="OpenIdConnectMessage"/>.
/// </summary>
public OpenIdConnectMessage ProtocolMessage { get; set; }
}
}

View File

@ -1,30 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNet.Http;
using Microsoft.Framework.Internal;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
namespace Microsoft.AspNet.Authentication.OpenIdConnect
{
/// <summary>
/// When a user configures the <see cref="AuthenticationMiddleware{TOptions}"/> to be notified prior to redirecting to an IdentityProvider
/// an instance of <see cref="RedirectToIdentityProviderContext"/> is passed to the 'RedirectToIdentityProvider" event.
/// </summary>
/// <typeparam name="TMessage">protocol specific message.</typeparam>
/// <typeparam name="TOptions">protocol specific options.</typeparam>
public class RedirectToIdentityProviderContext : BaseControlContext<OpenIdConnectOptions>
{
public RedirectToIdentityProviderContext([NotNull] HttpContext context, [NotNull] OpenIdConnectOptions options)
: base(context, options)
{
}
/// <summary>
/// Gets or sets the <see cref="OpenIdConnectMessage"/>.
/// </summary>
/// <exception cref="ArgumentNullException">if 'value' is null.</exception>
public OpenIdConnectMessage ProtocolMessage { get; [param: NotNull] set; }
}
}

View File

@ -6,21 +6,16 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
/// <summary> /// <summary>
/// This Context can be used to be informed when an 'AuthorizationCode' is redeemed for tokens at the token endpoint. /// This Context can be used to be informed when an 'AuthorizationCode' is redeemed for tokens at the token endpoint.
/// </summary> /// </summary>
public class AuthorizationCodeRedeemedContext : BaseControlContext<OpenIdConnectOptions> public class TokenResponseReceivedContext : BaseControlContext<OpenIdConnectOptions>
{ {
/// <summary> /// <summary>
/// Creates a <see cref="AuthorizationCodeRedeemedContext"/> /// Creates a <see cref="TokenResponseReceivedContext"/>
/// </summary> /// </summary>
public AuthorizationCodeRedeemedContext(HttpContext context, OpenIdConnectOptions options) public TokenResponseReceivedContext(HttpContext context, OpenIdConnectOptions options)
: base(context, options) : base(context, options)
{ {
} }
/// <summary>
/// Gets or sets the 'code'.
/// </summary>
public string Code { get; set; }
/// <summary> /// <summary>
/// Gets or sets the <see cref="OpenIdConnectTokenEndpointResponse"/> that contains the tokens and json response received after redeeming the code at the token endpoint. /// Gets or sets the <see cref="OpenIdConnectTokenEndpointResponse"/> that contains the tokens and json response received after redeeming the code at the token endpoint.
/// </summary> /// </summary>

View File

@ -0,0 +1,21 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Http;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Newtonsoft.Json.Linq;
namespace Microsoft.AspNet.Authentication.OpenIdConnect
{
public class UserInformationReceivedContext : BaseControlContext<OpenIdConnectOptions>
{
public UserInformationReceivedContext(HttpContext context, OpenIdConnectOptions options)
: base(context, options)
{
}
public OpenIdConnectMessage ProtocolMessage { get; set; }
public JObject User { get; set; }
}
}

View File

@ -74,7 +74,6 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
var message = new OpenIdConnectMessage() var message = new OpenIdConnectMessage()
{ {
IssuerAddress = _configuration == null ? string.Empty : (_configuration.EndSessionEndpoint ?? string.Empty), IssuerAddress = _configuration == null ? string.Empty : (_configuration.EndSessionEndpoint ?? string.Empty),
RequestType = OpenIdConnectRequestType.LogoutRequest,
}; };
// Set End_Session_Endpoint in order: // Set End_Session_Endpoint in order:
@ -90,24 +89,24 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
message.PostLogoutRedirectUri = Options.PostLogoutRedirectUri; message.PostLogoutRedirectUri = Options.PostLogoutRedirectUri;
} }
var redirectToIdentityProviderContext = new RedirectToIdentityProviderContext(Context, Options) var redirectContext = new RedirectContext(Context, Options)
{ {
ProtocolMessage = message ProtocolMessage = message
}; };
await Options.Events.RedirectToIdentityProvider(redirectToIdentityProviderContext); await Options.Events.RedirectToEndSessionEndpoint(redirectContext);
if (redirectToIdentityProviderContext.HandledResponse) if (redirectContext.HandledResponse)
{ {
Logger.LogVerbose(Resources.OIDCH_0034_RedirectToIdentityProviderContextHandledResponse); Logger.LogVerbose("RedirectToEndSessionEndpoint.HandledResponse");
return; return;
} }
else if (redirectToIdentityProviderContext.Skipped) else if (redirectContext.Skipped)
{ {
Logger.LogVerbose(Resources.OIDCH_0035_RedirectToIdentityProviderContextSkipped); Logger.LogVerbose("RedirectToEndSessionEndpoint.Skipped");
return; return;
} }
message = redirectToIdentityProviderContext.ProtocolMessage; message = redirectContext.ProtocolMessage;
if (Options.AuthenticationMethod == OpenIdConnectRedirectBehavior.RedirectGet) if (Options.AuthenticationMethod == OpenIdConnectRedirectBehavior.RedirectGet)
{ {
@ -183,8 +182,6 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
ClientId = Options.ClientId, ClientId = Options.ClientId,
IssuerAddress = _configuration?.AuthorizationEndpoint ?? string.Empty, IssuerAddress = _configuration?.AuthorizationEndpoint ?? string.Empty,
RedirectUri = Options.RedirectUri, RedirectUri = Options.RedirectUri,
// [brentschmaltz] - #215 this should be a property on RedirectToIdentityProviderContext not on the OIDCMessage.
RequestType = OpenIdConnectRequestType.AuthenticationRequest,
Resource = Options.Resource, Resource = Options.Resource,
ResponseType = Options.ResponseType, ResponseType = Options.ResponseType,
Scope = string.Join(" ", Options.Scope) Scope = string.Join(" ", Options.Scope)
@ -207,29 +204,29 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
GenerateCorrelationId(properties); GenerateCorrelationId(properties);
var redirectToIdentityProviderContext = new RedirectToIdentityProviderContext(Context, Options) var redirectContext = new RedirectContext(Context, Options)
{ {
ProtocolMessage = message ProtocolMessage = message
}; };
await Options.Events.RedirectToIdentityProvider(redirectToIdentityProviderContext); await Options.Events.RedirectToAuthenticationEndpoint(redirectContext);
if (redirectToIdentityProviderContext.HandledResponse) if (redirectContext.HandledResponse)
{ {
Logger.LogVerbose(Resources.OIDCH_0034_RedirectToIdentityProviderContextHandledResponse); Logger.LogVerbose("RedirectToAuthenticationEndpoint.HandledResponse");
return true; return true;
} }
else if (redirectToIdentityProviderContext.Skipped) else if (redirectContext.Skipped)
{ {
Logger.LogVerbose(Resources.OIDCH_0035_RedirectToIdentityProviderContextSkipped); Logger.LogVerbose("RedirectToAuthenticationEndpoint.Skipped");
return false; return false;
} }
if (!string.IsNullOrEmpty(redirectToIdentityProviderContext.ProtocolMessage.State)) message = redirectContext.ProtocolMessage;
{
properties.Items[OpenIdConnectDefaults.UserstatePropertiesKey] = redirectToIdentityProviderContext.ProtocolMessage.State;
}
message = redirectToIdentityProviderContext.ProtocolMessage; if (!string.IsNullOrEmpty(message.State))
{
properties.Items[OpenIdConnectDefaults.UserstatePropertiesKey] = message.State;
}
var redirectUriForCode = message.RedirectUri; var redirectUriForCode = message.RedirectUri;
if (string.IsNullOrEmpty(redirectUriForCode)) if (string.IsNullOrEmpty(redirectUriForCode))
@ -350,36 +347,35 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
{ {
return null; return null;
} }
message = messageReceivedContext.ProtocolMessage;
var properties = new AuthenticationProperties(); // Fail if state is missing, it's required for the correlation id.
// if state is missing, just log it
if (string.IsNullOrEmpty(message.State)) if (string.IsNullOrEmpty(message.State))
{ {
Logger.LogWarning(Resources.OIDCH_0004_MessageStateIsNullOrEmpty); Logger.LogError(Resources.OIDCH_0004_MessageStateIsNullOrEmpty);
return null;
} }
else
{
// if state exists and we failed to 'unprotect' this is not a message we should process.
properties = Options.StateDataFormat.Unprotect(Uri.UnescapeDataString(message.State));
if (properties == null)
{
Logger.LogError(Resources.OIDCH_0005_MessageStateIsInvalid);
return null;
}
string userstate = null; // if state exists and we failed to 'unprotect' this is not a message we should process.
properties.Items.TryGetValue(OpenIdConnectDefaults.UserstatePropertiesKey, out userstate); var properties = Options.StateDataFormat.Unprotect(Uri.UnescapeDataString(message.State));
message.State = userstate; if (properties == null)
{
Logger.LogError(Resources.OIDCH_0005_MessageStateIsInvalid);
return null;
} }
// if any of the error fields are set, throw error null // if any of the error fields are set, throw error null
if (!string.IsNullOrEmpty(message.Error)) if (!string.IsNullOrEmpty(message.Error))
{ {
Logger.LogError(Resources.OIDCH_0006_MessageContainsError, message.Error, message.ErrorDescription ?? "ErrorDecription null", message.ErrorUri ?? "ErrorUri null"); Logger.LogError(Resources.OIDCH_0006_MessageContainsError, message.Error, message.ErrorDescription ?? "ErrorDecription null", message.ErrorUri ?? "ErrorUri null");
throw new SecurityTokenException(string.Format(CultureInfo.InvariantCulture, Resources.OIDCH_0006_MessageContainsError, message.Error, message.ErrorDescription ?? "ErrorDecription null", message.ErrorUri ?? "ErrorUri null")); throw new OpenIdConnectProtocolException(string.Format(CultureInfo.InvariantCulture, Resources.OIDCH_0006_MessageContainsError, message.Error, message.ErrorDescription ?? "ErrorDecription null", message.ErrorUri ?? "ErrorUri null"));
} }
string userstate = null;
properties.Items.TryGetValue(OpenIdConnectDefaults.UserstatePropertiesKey, out userstate);
message.State = userstate;
if (!ValidateCorrelationId(properties)) if (!ValidateCorrelationId(properties))
{ {
return null; return null;
@ -391,6 +387,26 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
_configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted); _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted);
} }
Logger.LogDebug("Authorization response received.");
var authorizationResponseReceivedContext = new AuthorizationResponseReceivedContext(Context, Options)
{
ProtocolMessage = message,
Properties = properties
};
await Options.Events.AuthorizationResponseReceived(authorizationResponseReceivedContext);
if (authorizationResponseReceivedContext.HandledResponse)
{
Logger.LogVerbose("AuthorizationResponseReceived.HandledResponse");
return authorizationResponseReceivedContext.AuthenticationTicket;
}
else if (authorizationResponseReceivedContext.Skipped)
{
Logger.LogVerbose("AuthorizationResponseReceived.Skipped");
return null;
}
message = authorizationResponseReceivedContext.ProtocolMessage;
properties = authorizationResponseReceivedContext.Properties;
if (string.IsNullOrEmpty(message.IdToken) && !string.IsNullOrEmpty(message.Code)) if (string.IsNullOrEmpty(message.IdToken) && !string.IsNullOrEmpty(message.Code))
{ {
return await HandleCodeOnlyFlow(message, properties); return await HandleCodeOnlyFlow(message, properties);
@ -433,13 +449,12 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
} }
} }
// Authorization Code Flow
private async Task<AuthenticationTicket> HandleCodeOnlyFlow(OpenIdConnectMessage message, AuthenticationProperties properties) private async Task<AuthenticationTicket> HandleCodeOnlyFlow(OpenIdConnectMessage message, AuthenticationProperties properties)
{ {
AuthenticationTicket ticket = null; AuthenticationTicket ticket = null;
JwtSecurityToken jwt = null; JwtSecurityToken jwt = null;
OpenIdConnectTokenEndpointResponse tokenEndpointResponse = null;
string idToken = null;
var authorizationCodeReceivedContext = await RunAuthorizationCodeReceivedEventAsync(message, properties, ticket, jwt); var authorizationCodeReceivedContext = await RunAuthorizationCodeReceivedEventAsync(message, properties, ticket, jwt);
if (authorizationCodeReceivedContext.HandledResponse) if (authorizationCodeReceivedContext.HandledResponse)
{ {
@ -449,14 +464,15 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
{ {
return null; return null;
} }
message = authorizationCodeReceivedContext.ProtocolMessage;
var code = authorizationCodeReceivedContext.Code;
// Redeeming authorization code for tokens // Redeeming authorization code for tokens
Logger.LogDebug(Resources.OIDCH_0038_Redeeming_Auth_Code, message.Code); Logger.LogDebug(Resources.OIDCH_0038_Redeeming_Auth_Code, code);
tokenEndpointResponse = await RedeemAuthorizationCodeAsync(message.Code, authorizationCodeReceivedContext.RedirectUri); var tokenEndpointResponse = await RedeemAuthorizationCodeAsync(code, authorizationCodeReceivedContext.RedirectUri);
idToken = tokenEndpointResponse.Message.IdToken;
var authorizationCodeRedeemedContext = await RunAuthorizationCodeRedeemedEventAsync(message, tokenEndpointResponse); var authorizationCodeRedeemedContext = await RunTokenResponseReceivedEventAsync(message, tokenEndpointResponse);
if (authorizationCodeRedeemedContext.HandledResponse) if (authorizationCodeRedeemedContext.HandledResponse)
{ {
return authorizationCodeRedeemedContext.AuthenticationTicket; return authorizationCodeRedeemedContext.AuthenticationTicket;
@ -466,63 +482,61 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
return null; return null;
} }
message = authorizationCodeRedeemedContext.ProtocolMessage;
tokenEndpointResponse = authorizationCodeRedeemedContext.TokenEndpointResponse;
// no need to validate signature when token is received using "code flow" as per spec [http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation]. // no need to validate signature when token is received using "code flow" as per spec [http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation].
var validationParameters = Options.TokenValidationParameters.Clone(); var validationParameters = Options.TokenValidationParameters.Clone();
validationParameters.ValidateSignature = false; validationParameters.ValidateSignature = false;
ticket = ValidateToken(idToken, message, properties, validationParameters, out jwt); ticket = ValidateToken(tokenEndpointResponse.ProtocolMessage.IdToken, message, properties, validationParameters, out jwt);
await ValidateOpenIdConnectProtocolAsync(null, message); await ValidateOpenIdConnectProtocolAsync(null, message);
var authenticationValidatedContext = await RunAuthenticationValidatedEventAsync(message, ticket, tokenEndpointResponse);
if (authenticationValidatedContext.HandledResponse)
{
return authenticationValidatedContext.AuthenticationTicket;
}
else if (authenticationValidatedContext.Skipped)
{
return null;
}
ticket = authenticationValidatedContext.AuthenticationTicket;
if (Options.GetClaimsFromUserInfoEndpoint) if (Options.GetClaimsFromUserInfoEndpoint)
{ {
Logger.LogDebug(Resources.OIDCH_0040_Sending_Request_UIEndpoint); Logger.LogDebug(Resources.OIDCH_0040_Sending_Request_UIEndpoint);
ticket = await GetUserInformationAsync(properties, tokenEndpointResponse.Message, ticket); ticket = await GetUserInformationAsync(tokenEndpointResponse.ProtocolMessage, ticket);
}
var securityTokenValidatedContext = await RunSecurityTokenValidatedEventAsync(message, ticket);
if (securityTokenValidatedContext.HandledResponse)
{
return securityTokenValidatedContext.AuthenticationTicket;
}
else if (securityTokenValidatedContext.Skipped)
{
return null;
} }
return ticket; return ticket;
} }
// Implicit Flow or Hybrid Flow
private async Task<AuthenticationTicket> HandleIdTokenFlows(OpenIdConnectMessage message, AuthenticationProperties properties) private async Task<AuthenticationTicket> HandleIdTokenFlows(OpenIdConnectMessage message, AuthenticationProperties properties)
{ {
AuthenticationTicket ticket = null; Logger.LogDebug(Resources.OIDCH_0020_IdTokenReceived, message.IdToken);
JwtSecurityToken jwt = null; JwtSecurityToken jwt = null;
var securityTokenReceivedContext = await RunSecurityTokenReceivedEventAsync(message);
if (securityTokenReceivedContext.HandledResponse)
{
return securityTokenReceivedContext.AuthenticationTicket;
}
else if (securityTokenReceivedContext.Skipped)
{
return null;
}
var validationParameters = Options.TokenValidationParameters.Clone(); var validationParameters = Options.TokenValidationParameters.Clone();
ticket = ValidateToken(message.IdToken, message, properties, validationParameters, out jwt); var ticket = ValidateToken(message.IdToken, message, properties, validationParameters, out jwt);
await ValidateOpenIdConnectProtocolAsync(jwt, message); await ValidateOpenIdConnectProtocolAsync(jwt, message);
var securityTokenValidatedContext = await RunSecurityTokenValidatedEventAsync(message, ticket); var authenticationValidatedContext = await RunAuthenticationValidatedEventAsync(message, ticket, tokenEndpointResponse: null);
if (securityTokenValidatedContext.HandledResponse) if (authenticationValidatedContext.HandledResponse)
{ {
return securityTokenValidatedContext.AuthenticationTicket; return authenticationValidatedContext.AuthenticationTicket;
} }
else if (securityTokenValidatedContext.Skipped) else if (authenticationValidatedContext.Skipped)
{ {
return null; return null;
} }
message = authenticationValidatedContext.ProtocolMessage;
ticket = authenticationValidatedContext.AuthenticationTicket;
// Hybrid Flow
if (message.Code != null) if (message.Code != null)
{ {
var authorizationCodeReceivedContext = await RunAuthorizationCodeReceivedEventAsync(message, properties, ticket, jwt); var authorizationCodeReceivedContext = await RunAuthorizationCodeReceivedEventAsync(message, properties, ticket, jwt);
@ -534,6 +548,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
{ {
return null; return null;
} }
ticket = authorizationCodeReceivedContext.AuthenticationTicket;
} }
return ticket; return ticket;
@ -568,17 +583,12 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
/// <summary> /// <summary>
/// Goes to UserInfo endpoint to retrieve additional claims and add any unique claims to the given identity. /// Goes to UserInfo endpoint to retrieve additional claims and add any unique claims to the given identity.
/// </summary> /// </summary>
/// <param name="properties">Authentication Properties</param>
/// <param name="message">message that is being processed</param> /// <param name="message">message that is being processed</param>
/// <param name="ticket">authentication ticket with claims principal and identities</param> /// <param name="ticket">authentication ticket with claims principal and identities</param>
/// <returns>Authentication ticket with identity with additional claims, if any.</returns> /// <returns>Authentication ticket with identity with additional claims, if any.</returns>
protected virtual async Task<AuthenticationTicket> GetUserInformationAsync(AuthenticationProperties properties, OpenIdConnectMessage message, AuthenticationTicket ticket) protected virtual async Task<AuthenticationTicket> GetUserInformationAsync(OpenIdConnectMessage message, AuthenticationTicket ticket)
{ {
string userInfoEndpoint = null; string userInfoEndpoint = _configuration?.UserInfoEndpoint;
if (_configuration != null)
{
userInfoEndpoint = _configuration.UserInfoEndpoint;
}
if (string.IsNullOrEmpty(userInfoEndpoint)) if (string.IsNullOrEmpty(userInfoEndpoint))
{ {
@ -593,6 +603,18 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
var userInfoResponse = await responseMessage.Content.ReadAsStringAsync(); var userInfoResponse = await responseMessage.Content.ReadAsStringAsync();
var user = JObject.Parse(userInfoResponse); var user = JObject.Parse(userInfoResponse);
var userInformationReceivedContext = await RunUserInformationReceivedEventAsync(ticket, message, user);
if (userInformationReceivedContext.HandledResponse)
{
return userInformationReceivedContext.AuthenticationTicket;
}
else if (userInformationReceivedContext.Skipped)
{
return null;
}
ticket = userInformationReceivedContext.AuthenticationTicket;
user = userInformationReceivedContext.User;
var identity = (ClaimsIdentity)ticket.Principal.Identity; var identity = (ClaimsIdentity)ticket.Principal.Identity;
var subjectClaimType = identity.FindFirst(ClaimTypes.NameIdentifier); var subjectClaimType = identity.FindFirst(ClaimTypes.NameIdentifier);
if (subjectClaimType == null) if (subjectClaimType == null)
@ -846,68 +868,71 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
return authorizationCodeReceivedContext; return authorizationCodeReceivedContext;
} }
private async Task<AuthorizationCodeRedeemedContext> RunAuthorizationCodeRedeemedEventAsync(OpenIdConnectMessage message, OpenIdConnectTokenEndpointResponse tokenEndpointResponse) private async Task<TokenResponseReceivedContext> RunTokenResponseReceivedEventAsync(OpenIdConnectMessage message, OpenIdConnectTokenEndpointResponse tokenEndpointResponse)
{ {
Logger.LogDebug(Resources.OIDCH_0042_AuthorizationCodeRedeemed, message.Code); Logger.LogDebug("Token response received.");
var authorizationCodeRedeemedContext = new AuthorizationCodeRedeemedContext(Context, Options) var tokenResponseReceivedContext = new TokenResponseReceivedContext(Context, Options)
{ {
Code = message.Code,
ProtocolMessage = message, ProtocolMessage = message,
TokenEndpointResponse = tokenEndpointResponse TokenEndpointResponse = tokenEndpointResponse
}; };
await Options.Events.AuthorizationCodeRedeemed(authorizationCodeRedeemedContext); await Options.Events.TokenResponseReceived(tokenResponseReceivedContext);
if (authorizationCodeRedeemedContext.HandledResponse) if (tokenResponseReceivedContext.HandledResponse)
{ {
Logger.LogVerbose(Resources.OIDCH_0043_AuthorizationCodeRedeemedContextHandledResponse); Logger.LogVerbose(Resources.OIDCH_0043_AuthorizationCodeRedeemedContextHandledResponse);
} }
else if (authorizationCodeRedeemedContext.Skipped) else if (tokenResponseReceivedContext.Skipped)
{ {
Logger.LogVerbose(Resources.OIDCH_0044_AuthorizationCodeRedeemedContextSkipped); Logger.LogVerbose(Resources.OIDCH_0044_AuthorizationCodeRedeemedContextSkipped);
} }
return authorizationCodeRedeemedContext; return tokenResponseReceivedContext;
} }
private async Task<SecurityTokenReceivedContext> RunSecurityTokenReceivedEventAsync(OpenIdConnectMessage message) private async Task<AuthenticationValidatedContext> RunAuthenticationValidatedEventAsync(OpenIdConnectMessage message, AuthenticationTicket ticket, OpenIdConnectTokenEndpointResponse tokenEndpointResponse)
{ {
Logger.LogDebug(Resources.OIDCH_0020_IdTokenReceived, message.IdToken); var authenticationValidatedContext = new AuthenticationValidatedContext(Context, Options)
var securityTokenReceivedContext = new SecurityTokenReceivedContext(Context, Options)
{
ProtocolMessage = message,
};
await Options.Events.SecurityTokenReceived(securityTokenReceivedContext);
if (securityTokenReceivedContext.HandledResponse)
{
Logger.LogVerbose(Resources.OIDCH_0008_SecurityTokenReceivedContextHandledResponse);
}
else if (securityTokenReceivedContext.Skipped)
{
Logger.LogVerbose(Resources.OIDCH_0009_SecurityTokenReceivedContextSkipped);
}
return securityTokenReceivedContext;
}
private async Task<SecurityTokenValidatedContext> RunSecurityTokenValidatedEventAsync(OpenIdConnectMessage message, AuthenticationTicket ticket)
{
var securityTokenValidatedContext = new SecurityTokenValidatedContext(Context, Options)
{ {
AuthenticationTicket = ticket, AuthenticationTicket = ticket,
ProtocolMessage = message ProtocolMessage = message,
TokenEndpointResponse = tokenEndpointResponse,
}; };
await Options.Events.SecurityTokenValidated(securityTokenValidatedContext); await Options.Events.AuthenticationValidated(authenticationValidatedContext);
if (securityTokenValidatedContext.HandledResponse) if (authenticationValidatedContext.HandledResponse)
{ {
Logger.LogVerbose(Resources.OIDCH_0012_SecurityTokenValidatedContextHandledResponse); Logger.LogVerbose("AuthenticationValidated.HandledResponse");
} }
else if (securityTokenValidatedContext.Skipped) else if (authenticationValidatedContext.Skipped)
{ {
Logger.LogVerbose(Resources.OIDCH_0013_SecurityTokenValidatedContextSkipped); Logger.LogVerbose("AuthenticationValidated.Skipped");
} }
return securityTokenValidatedContext; return authenticationValidatedContext;
}
private async Task<UserInformationReceivedContext> RunUserInformationReceivedEventAsync(AuthenticationTicket ticket, OpenIdConnectMessage message, JObject user)
{
Logger.LogDebug("User information received:" + user.ToString());
var userInformationReceivedContext = new UserInformationReceivedContext(Context, Options)
{
AuthenticationTicket = ticket,
ProtocolMessage = message,
User = user,
};
await Options.Events.UserInformationReceived(userInformationReceivedContext);
if (userInformationReceivedContext.HandledResponse)
{
Logger.LogVerbose("The UserInformationReceived event returned Handled.");
}
else if (userInformationReceivedContext.Skipped)
{
Logger.LogVerbose("The UserInformationReceived event returned Skipped.");
}
return userInformationReceivedContext;
} }
private async Task<AuthenticationFailedContext> RunAuthenticationFailedEventAsync(OpenIdConnectMessage message, Exception exception) private async Task<AuthenticationFailedContext> RunAuthenticationFailedEventAsync(OpenIdConnectMessage message, Exception exception)
@ -980,7 +1005,6 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
ticket.Properties.Items[OpenIdConnectSessionProperties.CheckSessionIFrame] = _configuration.CheckSessionIframe; ticket.Properties.Items[OpenIdConnectSessionProperties.CheckSessionIFrame] = _configuration.CheckSessionIframe;
} }
// Rename?
if (Options.UseTokenLifetime) if (Options.UseTokenLifetime)
{ {
var issued = validatedToken.ValidFrom; var issued = validatedToken.ValidFrom;
@ -1024,14 +1048,33 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
/// <returns>True if the request was handled, false if the next middleware should be invoked.</returns> /// <returns>True if the request was handled, false if the next middleware should be invoked.</returns>
public override Task<bool> InvokeAsync() public override Task<bool> InvokeAsync()
{ {
return InvokeReplyPathAsync(); return InvokeReturnPathAsync();
} }
private async Task<bool> InvokeReplyPathAsync() private async Task<bool> InvokeReturnPathAsync()
{ {
var ticket = await HandleAuthenticateOnceAsync(); var ticket = await HandleAuthenticateOnceAsync();
if (ticket != null) if (ticket != null)
{ {
Logger.LogDebug("Authentication completed.");
var authenticationCompletedContext = new AuthenticationCompletedContext(Context, Options)
{
AuthenticationTicket = ticket,
};
await Options.Events.AuthenticationCompleted(authenticationCompletedContext);
if (authenticationCompletedContext.HandledResponse)
{
Logger.LogVerbose("The AuthenticationCompleted event returned Handled.");
return true;
}
else if (authenticationCompletedContext.Skipped)
{
Logger.LogVerbose("The AuthenticationCompleted event returned Skipped.");
return false;
}
ticket = authenticationCompletedContext.AuthenticationTicket;
if (ticket.Principal != null) if (ticket.Principal != null)
{ {
await Request.HttpContext.Authentication.SignInAsync(Options.SignInScheme, ticket.Principal, ticket.Properties); await Request.HttpContext.Authentication.SignInAsync(Options.SignInScheme, ticket.Principal, ticket.Properties);

View File

@ -1,7 +1,6 @@
using System; // Copyright (c) .NET Foundation. All rights reserved.
using System.Collections.Generic; // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@ -15,7 +14,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
public OpenIdConnectTokenEndpointResponse(JObject jsonResponse) public OpenIdConnectTokenEndpointResponse(JObject jsonResponse)
{ {
JsonResponse = jsonResponse; JsonResponse = jsonResponse;
Message = new OpenIdConnectMessage() ProtocolMessage = new OpenIdConnectMessage()
{ {
AccessToken = JsonResponse.Value<string>(OpenIdConnectParameterNames.AccessToken), AccessToken = JsonResponse.Value<string>(OpenIdConnectParameterNames.AccessToken),
IdToken = JsonResponse.Value<string>(OpenIdConnectParameterNames.IdToken), IdToken = JsonResponse.Value<string>(OpenIdConnectParameterNames.IdToken),
@ -27,7 +26,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
/// <summary> /// <summary>
/// OpenIdConnect message that contains the id token and access tokens /// OpenIdConnect message that contains the id token and access tokens
/// </summary> /// </summary>
public OpenIdConnectMessage Message { get; set; } public OpenIdConnectMessage ProtocolMessage { get; set; }
/// <summary> /// <summary>
/// Json response returned from the token endpoint /// Json response returned from the token endpoint

View File

@ -186,38 +186,6 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
return string.Format(CultureInfo.CurrentCulture, GetString("OIDCH_0033_NonceAlreadyExists"), p0); return string.Format(CultureInfo.CurrentCulture, GetString("OIDCH_0033_NonceAlreadyExists"), p0);
} }
/// <summary>
/// OIDCH_0034: RedirectToIdentityProviderContext.HandledResponse
/// </summary>
internal static string OIDCH_0034_RedirectToIdentityProviderContextHandledResponse
{
get { return GetString("OIDCH_0034_RedirectToIdentityProviderContextHandledResponse"); }
}
/// <summary>
/// OIDCH_0034: RedirectToIdentityProviderContext.HandledResponse
/// </summary>
internal static string FormatOIDCH_0034_RedirectToIdentityProviderContextHandledResponse()
{
return GetString("OIDCH_0034_RedirectToIdentityProviderContextHandledResponse");
}
/// <summary>
/// OIDCH_0035: RedirectToIdentityProviderContext.Skipped
/// </summary>
internal static string OIDCH_0035_RedirectToIdentityProviderContextSkipped
{
get { return GetString("OIDCH_0035_RedirectToIdentityProviderContextSkipped"); }
}
/// <summary>
/// OIDCH_0035: RedirectToIdentityProviderContext.Skipped
/// </summary>
internal static string FormatOIDCH_0035_RedirectToIdentityProviderContextSkipped()
{
return GetString("OIDCH_0035_RedirectToIdentityProviderContextSkipped");
}
/// <summary> /// <summary>
/// OIDCH_0036: Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute) returned 'false', redirectUri is: '{0}'. /// OIDCH_0036: Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute) returned 'false', redirectUri is: '{0}'.
/// </summary> /// </summary>
@ -426,38 +394,6 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
return GetString("OIDCH_0007_UpdatingConfiguration"); return GetString("OIDCH_0007_UpdatingConfiguration");
} }
/// <summary>
/// OIDCH_0008: SecurityTokenReceivedContext.HandledResponse
/// </summary>
internal static string OIDCH_0008_SecurityTokenReceivedContextHandledResponse
{
get { return GetString("OIDCH_0008_SecurityTokenReceivedContextHandledResponse"); }
}
/// <summary>
/// OIDCH_0008: SecurityTokenReceivedContext.HandledResponse
/// </summary>
internal static string FormatOIDCH_0008_SecurityTokenReceivedContextHandledResponse()
{
return GetString("OIDCH_0008_SecurityTokenReceivedContextHandledResponse");
}
/// <summary>
/// OIDCH_0009: SecurityTokenReceivedContext.Skipped
/// </summary>
internal static string OIDCH_0009_SecurityTokenReceivedContextSkipped
{
get { return GetString("OIDCH_0009_SecurityTokenReceivedContextSkipped"); }
}
/// <summary>
/// OIDCH_0009: SecurityTokenReceivedContext.Skipped
/// </summary>
internal static string FormatOIDCH_0009_SecurityTokenReceivedContextSkipped()
{
return GetString("OIDCH_0009_SecurityTokenReceivedContextSkipped");
}
/// <summary> /// <summary>
/// OIDCH_0010: Validated Security Token must be a JwtSecurityToken was: '{0}'. /// OIDCH_0010: Validated Security Token must be a JwtSecurityToken was: '{0}'.
/// </summary> /// </summary>
@ -490,38 +426,6 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
return string.Format(CultureInfo.CurrentCulture, GetString("OIDCH_0011_UnableToValidateToken"), p0); return string.Format(CultureInfo.CurrentCulture, GetString("OIDCH_0011_UnableToValidateToken"), p0);
} }
/// <summary>
/// OIDCH_0012: SecurityTokenValidatedContext.HandledResponse
/// </summary>
internal static string OIDCH_0012_SecurityTokenValidatedContextHandledResponse
{
get { return GetString("OIDCH_0012_SecurityTokenValidatedContextHandledResponse"); }
}
/// <summary>
/// OIDCH_0012: SecurityTokenValidatedContext.HandledResponse
/// </summary>
internal static string FormatOIDCH_0012_SecurityTokenValidatedContextHandledResponse()
{
return GetString("OIDCH_0012_SecurityTokenValidatedContextHandledResponse");
}
/// <summary>
/// OIDCH_0013: SecurityTokenValidatedContext.Skipped
/// </summary>
internal static string OIDCH_0013_SecurityTokenValidatedContextSkipped
{
get { return GetString("OIDCH_0013_SecurityTokenValidatedContextSkipped"); }
}
/// <summary>
/// OIDCH_0013: SecurityTokenValidatedContext.Skipped
/// </summary>
internal static string FormatOIDCH_0013_SecurityTokenValidatedContextSkipped()
{
return GetString("OIDCH_0013_SecurityTokenValidatedContextSkipped");
}
/// <summary> /// <summary>
/// OIDCH_0014: AuthorizationCode received: '{0}'. /// OIDCH_0014: AuthorizationCode received: '{0}'.
/// </summary> /// </summary>
@ -666,22 +570,6 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
return string.Format(CultureInfo.CurrentCulture, GetString("OIDCH_0041_Subject_Claim_Not_Found"), p0); return string.Format(CultureInfo.CurrentCulture, GetString("OIDCH_0041_Subject_Claim_Not_Found"), p0);
} }
/// <summary>
/// OIDCH_0042: Authorization Code redeemed: '{0}'
/// </summary>
internal static string OIDCH_0042_AuthorizationCodeRedeemed
{
get { return GetString("OIDCH_0042_AuthorizationCodeRedeemed"); }
}
/// <summary>
/// OIDCH_0042: Authorization Code redeemed: '{0}'
/// </summary>
internal static string FormatOIDCH_0042_AuthorizationCodeRedeemed(object p0)
{
return string.Format(CultureInfo.CurrentCulture, GetString("OIDCH_0042_AuthorizationCodeRedeemed"), p0);
}
/// <summary> /// <summary>
/// OIDCH_0043: AuthorizationCodeRedeemedContext.HandledResponse /// OIDCH_0043: AuthorizationCodeRedeemedContext.HandledResponse
/// </summary> /// </summary>

View File

@ -150,12 +150,6 @@
<data name="OIDCH_0033_NonceAlreadyExists" xml:space="preserve"> <data name="OIDCH_0033_NonceAlreadyExists" xml:space="preserve">
<value>OIDCH_0033: ProtocolValidator.RequireNonce == true. The generated nonce already exists: this usually indicates the nonce is not unique or has been used. The nonce is: '{0}'.</value> <value>OIDCH_0033: ProtocolValidator.RequireNonce == true. The generated nonce already exists: this usually indicates the nonce is not unique or has been used. The nonce is: '{0}'.</value>
</data> </data>
<data name="OIDCH_0034_RedirectToIdentityProviderContextHandledResponse" xml:space="preserve">
<value>OIDCH_0034: RedirectToIdentityProviderContext.HandledResponse</value>
</data>
<data name="OIDCH_0035_RedirectToIdentityProviderContextSkipped" xml:space="preserve">
<value>OIDCH_0035: RedirectToIdentityProviderContext.Skipped</value>
</data>
<data name="OIDCH_0036_UriIsNotWellFormed" xml:space="preserve"> <data name="OIDCH_0036_UriIsNotWellFormed" xml:space="preserve">
<value>OIDCH_0036: Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute) returned 'false', redirectUri is: '{0}'.</value> <value>OIDCH_0036: Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute) returned 'false', redirectUri is: '{0}'.</value>
</data> </data>
@ -195,24 +189,12 @@
<data name="OIDCH_0007_UpdatingConfiguration" xml:space="preserve"> <data name="OIDCH_0007_UpdatingConfiguration" xml:space="preserve">
<value>OIDCH_0007: Updating configuration</value> <value>OIDCH_0007: Updating configuration</value>
</data> </data>
<data name="OIDCH_0008_SecurityTokenReceivedContextHandledResponse" xml:space="preserve">
<value>OIDCH_0008: SecurityTokenReceivedContext.HandledResponse</value>
</data>
<data name="OIDCH_0009_SecurityTokenReceivedContextSkipped" xml:space="preserve">
<value>OIDCH_0009: SecurityTokenReceivedContext.Skipped</value>
</data>
<data name="OIDCH_0010_ValidatedSecurityTokenNotJwt" xml:space="preserve"> <data name="OIDCH_0010_ValidatedSecurityTokenNotJwt" xml:space="preserve">
<value>OIDCH_0010: Validated Security Token must be a JwtSecurityToken was: '{0}'.</value> <value>OIDCH_0010: Validated Security Token must be a JwtSecurityToken was: '{0}'.</value>
</data> </data>
<data name="OIDCH_0011_UnableToValidateToken" xml:space="preserve"> <data name="OIDCH_0011_UnableToValidateToken" xml:space="preserve">
<value>OIDCH_0011: Unable to validate the 'id_token', no suitable ISecurityTokenValidator was found for: '{0}'."</value> <value>OIDCH_0011: Unable to validate the 'id_token', no suitable ISecurityTokenValidator was found for: '{0}'."</value>
</data> </data>
<data name="OIDCH_0012_SecurityTokenValidatedContextHandledResponse" xml:space="preserve">
<value>OIDCH_0012: SecurityTokenValidatedContext.HandledResponse</value>
</data>
<data name="OIDCH_0013_SecurityTokenValidatedContextSkipped" xml:space="preserve">
<value>OIDCH_0013: SecurityTokenValidatedContext.Skipped</value>
</data>
<data name="OIDCH_0014_AuthorizationCodeReceived" xml:space="preserve"> <data name="OIDCH_0014_AuthorizationCodeReceived" xml:space="preserve">
<value>OIDCH_0014: AuthorizationCode received: '{0}'.</value> <value>OIDCH_0014: AuthorizationCode received: '{0}'.</value>
</data> </data>
@ -240,9 +222,6 @@
<data name="OIDCH_0041_Subject_Claim_Not_Found" xml:space="preserve"> <data name="OIDCH_0041_Subject_Claim_Not_Found" xml:space="preserve">
<value>OIDCH_0041: Subject claim not found in {0}.</value> <value>OIDCH_0041: Subject claim not found in {0}.</value>
</data> </data>
<data name="OIDCH_0042_AuthorizationCodeRedeemed" xml:space="preserve">
<value>OIDCH_0042: Authorization Code redeemed: '{0}'</value>
</data>
<data name="OIDCH_0043_AuthorizationCodeRedeemedContextHandledResponse" xml:space="preserve"> <data name="OIDCH_0043_AuthorizationCodeRedeemedContextHandledResponse" xml:space="preserve">
<value>OIDCH_0043: AuthorizationCodeRedeemedContext.HandledResponse</value> <value>OIDCH_0043: AuthorizationCodeRedeemedContext.HandledResponse</value>
</data> </data>

View File

@ -5,13 +5,11 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Features; using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Http.Features.Authentication; using Microsoft.AspNet.Http.Features.Authentication;
using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Http.Internal;
using Microsoft.Framework.Logging; using Microsoft.Framework.Logging;
using Microsoft.Framework.Primitives; using Microsoft.Framework.Primitives;
using Moq;
using Xunit; using Xunit;
namespace Microsoft.AspNet.Authentication namespace Microsoft.AspNet.Authentication

View File

@ -33,7 +33,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
return Task.FromResult(new OpenIdConnectTokenEndpointResponse(jsonResponse)); return Task.FromResult(new OpenIdConnectTokenEndpointResponse(jsonResponse));
} }
protected override Task<AuthenticationTicket> GetUserInformationAsync(AuthenticationProperties properties, OpenIdConnectMessage message, AuthenticationTicket ticket) protected override Task<AuthenticationTicket> GetUserInformationAsync(OpenIdConnectMessage message, AuthenticationTicket ticket)
{ {
var claimsIdentity = (ClaimsIdentity)ticket.Principal.Identity; var claimsIdentity = (ClaimsIdentity)ticket.Principal.Identity;
if (claimsIdentity == null) if (claimsIdentity == null)

View File

@ -3,7 +3,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IdentityModel.Tokens; using System.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
using System.Linq; using System.Linq;
@ -19,7 +18,6 @@ using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel; using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.WebEncoders; using Microsoft.Framework.WebEncoders;
using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Moq;
using Xunit; using Xunit;
namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
@ -56,7 +54,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
Assert.False(logger.IsEnabled(LogLevel.Warning)); Assert.False(logger.IsEnabled(LogLevel.Warning));
} }
[Theory, MemberData("AuthenticateCoreStateDataSet")] [Theory, MemberData(nameof(AuthenticateCoreStateDataSet))]
public async Task AuthenticateCoreState(Action<OpenIdConnectOptions> action, OpenIdConnectMessage message) public async Task AuthenticateCoreState(Action<OpenIdConnectOptions> action, OpenIdConnectMessage message)
{ {
var handler = new OpenIdConnectHandlerForTestingAuthenticate(); var handler = new OpenIdConnectHandlerForTestingAuthenticate();
@ -103,7 +101,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
options.StateDataFormat = new AuthenticationPropertiesFormaterKeyValue(); options.StateDataFormat = new AuthenticationPropertiesFormaterKeyValue();
options.Events = new OpenIdConnectEvents() options.Events = new OpenIdConnectEvents()
{ {
OnAuthorizationCodeRedeemed = context => OnTokenResponseReceived = context =>
{ {
context.HandleResponse(); context.HandleResponse();
if (context.ProtocolMessage.State == null && !context.ProtocolMessage.Parameters.ContainsKey(ExpectedStateParameter)) if (context.ProtocolMessage.State == null && !context.ProtocolMessage.Parameters.ContainsKey(ExpectedStateParameter))
@ -118,271 +116,6 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
}; };
} }
#region Configure Options for AuthenticateCore variations
private static void DefaultOptions(OpenIdConnectOptions options)
{
options.AuthenticationScheme = "OpenIdConnectHandlerTest";
options.SignInScheme = "OpenIdConnectHandlerTest";
options.ConfigurationManager = TestUtilities.DefaultOpenIdConnectConfigurationManager;
options.ClientId = Guid.NewGuid().ToString();
options.StateDataFormat = new AuthenticationPropertiesFormaterKeyValue();
}
private static void AuthorizationCodeReceivedHandledOptions(OpenIdConnectOptions options)
{
DefaultOptions(options);
options.SecurityTokenValidator = MockSecurityTokenValidator();
options.ProtocolValidator = MockProtocolValidator();
options.Events = new OpenIdConnectEvents()
{
OnAuthorizationCodeReceived = (context) =>
{
context.HandleResponse();
return Task.FromResult<object>(null);
}
};
}
private static void AuthorizationCodeReceivedSkippedOptions(OpenIdConnectOptions options)
{
DefaultOptions(options);
options.SecurityTokenValidator = MockSecurityTokenValidator();
options.ProtocolValidator = MockProtocolValidator();
options.Events = new OpenIdConnectEvents()
{
OnAuthorizationCodeReceived = (context) =>
{
context.SkipToNextMiddleware();
return Task.FromResult<object>(null);
}
};
}
private static void AuthenticationErrorHandledOptions(OpenIdConnectOptions options)
{
DefaultOptions(options);
options.SecurityTokenValidator = MockSecurityTokenValidator();
options.ProtocolValidator = MockProtocolValidator();
options.Events = new OpenIdConnectEvents()
{
OnAuthenticationFailed = (context) =>
{
context.HandleResponse();
return Task.FromResult<object>(null);
}
};
}
private static void AuthenticationErrorSkippedOptions(OpenIdConnectOptions options)
{
DefaultOptions(options);
options.SecurityTokenValidator = MockSecurityTokenValidator();
options.ProtocolValidator = MockProtocolValidator();
options.Events = new OpenIdConnectEvents()
{
OnAuthenticationFailed = (context) =>
{
context.SkipToNextMiddleware();
return Task.FromResult<object>(null);
}
};
}
private static void MessageReceivedHandledOptions(OpenIdConnectOptions options)
{
DefaultOptions(options);
options.Events = new OpenIdConnectEvents()
{
OnMessageReceived = (context) =>
{
context.HandleResponse();
return Task.FromResult<object>(null);
}
};
}
private static void CodeReceivedAndRedeemedHandledOptions(OpenIdConnectOptions options)
{
DefaultOptions(options);
options.ResponseType = OpenIdConnectResponseTypes.Code;
options.StateDataFormat = new AuthenticationPropertiesFormaterKeyValue();
options.Events = new OpenIdConnectEvents()
{
OnAuthorizationCodeRedeemed = (context) =>
{
context.HandleResponse();
return Task.FromResult<object>(null);
}
};
}
private static void CodeReceivedAndRedeemedSkippedOptions(OpenIdConnectOptions options)
{
DefaultOptions(options);
options.ResponseType = OpenIdConnectResponseTypes.Code;
options.StateDataFormat = new AuthenticationPropertiesFormaterKeyValue();
options.Events = new OpenIdConnectEvents()
{
OnAuthorizationCodeRedeemed = (context) =>
{
context.SkipToNextMiddleware();
return Task.FromResult<object>(null);
}
};
}
private static void GetUserInfoFromUIEndpoint(OpenIdConnectOptions options)
{
DefaultOptions(options);
options.ResponseType = OpenIdConnectResponseTypes.Code;
options.ProtocolValidator.RequireNonce = false;
options.StateDataFormat = new AuthenticationPropertiesFormaterKeyValue();
options.GetClaimsFromUserInfoEndpoint = true;
options.SecurityTokenValidator = MockSecurityTokenValidator();
options.Events = new OpenIdConnectEvents()
{
OnSecurityTokenValidated = (context) =>
{
var claimValue = context.AuthenticationTicket.Principal.FindFirst("test claim");
Assert.Equal(claimValue.Value, "test value");
context.HandleResponse();
return Task.FromResult<object>(null);
}
};
}
private static void MessageReceivedSkippedOptions(OpenIdConnectOptions options)
{
DefaultOptions(options);
options.Events = new OpenIdConnectEvents()
{
OnMessageReceived = (context) =>
{
context.SkipToNextMiddleware();
return Task.FromResult<object>(null);
}
};
}
private static void MessageWithErrorOptions(OpenIdConnectOptions options)
{
AuthenticationErrorHandledOptions(options);
}
private static void SecurityTokenReceivedHandledOptions(OpenIdConnectOptions options)
{
DefaultOptions(options);
options.Events = new OpenIdConnectEvents()
{
OnSecurityTokenReceived = (context) =>
{
context.HandleResponse();
return Task.FromResult<object>(null);
}
};
}
private static void SecurityTokenReceivedSkippedOptions(OpenIdConnectOptions options)
{
DefaultOptions(options);
options.Events = new OpenIdConnectEvents()
{
OnSecurityTokenReceived = (context) =>
{
context.SkipToNextMiddleware();
return Task.FromResult<object>(null);
}
};
}
private static ISecurityTokenValidator MockSecurityTokenValidator()
{
var mockValidator = new Mock<ISecurityTokenValidator>();
mockValidator.Setup(v => v.ValidateToken(It.IsAny<string>(), It.IsAny<TokenValidationParameters>(), out specCompliantJwt)).Returns(new ClaimsPrincipal());
mockValidator.Setup(v => v.CanReadToken(It.IsAny<string>())).Returns(true);
return mockValidator.Object;
}
private static OpenIdConnectProtocolValidator MockProtocolValidator()
{
var mockProtocolValidator = new Mock<OpenIdConnectProtocolValidator>();
mockProtocolValidator.Setup(v => v.Validate(It.IsAny<JwtSecurityToken>(), It.IsAny<OpenIdConnectProtocolValidationContext>()));
return mockProtocolValidator.Object;
}
private static void SecurityTokenValidatorCannotReadToken(OpenIdConnectOptions options)
{
AuthenticationErrorHandledOptions(options);
var mockValidator = new Mock<ISecurityTokenValidator>();
SecurityToken jwt = null;
mockValidator.Setup(v => v.ValidateToken(It.IsAny<string>(), It.IsAny<TokenValidationParameters>(), out jwt)).Returns(new ClaimsPrincipal());
mockValidator.Setup(v => v.CanReadToken(It.IsAny<string>())).Returns(false);
options.SecurityTokenValidator = mockValidator.Object;
}
private static void SecurityTokenValidatorThrows(OpenIdConnectOptions options)
{
AuthenticationErrorHandledOptions(options);
var mockValidator = new Mock<ISecurityTokenValidator>();
SecurityToken jwt = null;
mockValidator.Setup(v => v.ValidateToken(It.IsAny<string>(), It.IsAny<TokenValidationParameters>(), out jwt)).Throws<SecurityTokenSignatureKeyNotFoundException>();
mockValidator.Setup(v => v.CanReadToken(It.IsAny<string>())).Returns(true);
options.SecurityTokenValidator = mockValidator.Object;
}
private static void SecurityTokenValidatorValidatesAllTokens(OpenIdConnectOptions options)
{
DefaultOptions(options);
options.SecurityTokenValidator = MockSecurityTokenValidator();
options.ProtocolValidator.RequireTimeStampInNonce = false;
options.ProtocolValidator.RequireNonce = false;
}
private static void SecurityTokenValidatedHandledOptions(OpenIdConnectOptions options)
{
SecurityTokenValidatorValidatesAllTokens(options);
options.Events = new OpenIdConnectEvents()
{
OnSecurityTokenValidated = (context) =>
{
context.HandleResponse();
return Task.FromResult<object>(null);
}
};
}
private static void SecurityTokenValidatedSkippedOptions(OpenIdConnectOptions options)
{
SecurityTokenValidatorValidatesAllTokens(options);
options.Events = new OpenIdConnectEvents()
{
OnSecurityTokenValidated = (context) =>
{
context.SkipToNextMiddleware();
return Task.FromResult<object>(null);
}
};
}
private static void StateNullOptions(OpenIdConnectOptions options)
{
DefaultOptions(options);
}
private static void StateEmptyOptions(OpenIdConnectOptions options)
{
DefaultOptions(options);
}
private static void StateInvalidOptions(OpenIdConnectOptions options)
{
DefaultOptions(options);
}
#endregion
private static Task EmptyTask() { return Task.FromResult(0); }
private static TestServer CreateServer(ConfigureOptions<OpenIdConnectOptions> options, IUrlEncoder encoder, OpenIdConnectHandler handler = null) private static TestServer CreateServer(ConfigureOptions<OpenIdConnectOptions> options, IUrlEncoder encoder, OpenIdConnectHandler handler = null)
{ {
return TestServer.Create( return TestServer.Create(
@ -401,24 +134,5 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
} }
); );
} }
private static TestServer CreateServer(ConfigureOptions<OpenIdConnectOptions> configureOptions, IUrlEncoder encoder, ILoggerFactory loggerFactory, OpenIdConnectHandler handler = null)
{
return TestServer.Create(
app =>
{
app.UseMiddleware<OpenIdConnectMiddlewareForTestingAuthenticate>(configureOptions, encoder, loggerFactory, handler);
app.Use(async (context, next) =>
{
await next();
});
},
services =>
{
services.AddWebEncoders();
services.AddDataProtection();
}
);
}
} }
} }

View File

@ -106,28 +106,47 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
} }
/// <summary> /// <summary>
/// Tests RedirectToIdentityProviderContext replaces the OpenIdConnectMesssage correctly. /// Tests RedirectForAuthenticationContext replaces the OpenIdConnectMesssage correctly.
/// </summary> /// </summary>
/// <returns>Task</returns> /// <returns>Task</returns>
[Theory] [Fact]
[InlineData(Challenge, OpenIdConnectRequestType.AuthenticationRequest)] public async Task ChallengeSettingMessage()
[InlineData(Signout, OpenIdConnectRequestType.LogoutRequest)]
public async Task ChallengeSettingMessage(string challenge, OpenIdConnectRequestType requestType)
{ {
var configuration = new OpenIdConnectConfiguration var configuration = new OpenIdConnectConfiguration
{ {
AuthorizationEndpoint = ExpectedAuthorizeRequest, AuthorizationEndpoint = ExpectedAuthorizeRequest,
};
var queryValues = new ExpectedQueryValues(DefaultAuthority, configuration)
{
RequestType = OpenIdConnectRequestType.AuthenticationRequest
};
var server = CreateServer(SetProtocolMessageOptions);
var transaction = await SendAsync(server, DefaultHost + Challenge);
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
queryValues.CheckValues(transaction.Response.Headers.Location.AbsoluteUri, new string[] {});
}
/// <summary>
/// Tests RedirectForSignOutContext replaces the OpenIdConnectMesssage correctly.
/// </summary>
/// <returns>Task</returns>
[Fact]
public async Task SignOutSettingMessage()
{
var configuration = new OpenIdConnectConfiguration
{
EndSessionEndpoint = ExpectedLogoutRequest EndSessionEndpoint = ExpectedLogoutRequest
}; };
var queryValues = new ExpectedQueryValues(DefaultAuthority, configuration) var queryValues = new ExpectedQueryValues(DefaultAuthority, configuration)
{ {
RequestType = requestType RequestType = OpenIdConnectRequestType.LogoutRequest
}; };
var server = CreateServer(SetProtocolMessageOptions); var server = CreateServer(SetProtocolMessageOptions);
var transaction = await SendAsync(server, DefaultHost + challenge); var transaction = await SendAsync(server, DefaultHost + Signout);
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
queryValues.CheckValues(transaction.Response.Headers.Location.AbsoluteUri, new string[] {}); queryValues.CheckValues(transaction.Response.Headers.Location.AbsoluteUri, new string[] { });
} }
private static void SetProtocolMessageOptions(OpenIdConnectOptions options) private static void SetProtocolMessageOptions(OpenIdConnectOptions options)
@ -138,7 +157,12 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
options.AutomaticAuthentication = true; options.AutomaticAuthentication = true;
options.Events = new OpenIdConnectEvents() options.Events = new OpenIdConnectEvents()
{ {
OnRedirectToIdentityProvider = (context) => OnRedirectToAuthenticationEndpoint = (context) =>
{
context.ProtocolMessage = mockOpenIdConnectMessage.Object;
return Task.FromResult<object>(null);
},
OnRedirectToEndSessionEndpoint = (context) =>
{ {
context.ProtocolMessage = mockOpenIdConnectMessage.Object; context.ProtocolMessage = mockOpenIdConnectMessage.Object;
return Task.FromResult<object>(null); return Task.FromResult<object>(null);
@ -170,7 +194,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
options.AutomaticAuthentication = challenge.Equals(ChallengeWithOutContext); options.AutomaticAuthentication = challenge.Equals(ChallengeWithOutContext);
options.Events = new OpenIdConnectEvents() options.Events = new OpenIdConnectEvents()
{ {
OnRedirectToIdentityProvider = context => OnRedirectToAuthenticationEndpoint = context =>
{ {
context.ProtocolMessage.State = userState; context.ProtocolMessage.State = userState;
return Task.FromResult<object>(null); return Task.FromResult<object>(null);
@ -221,7 +245,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
SetOptions(options, DefaultParameters(), queryValues); SetOptions(options, DefaultParameters(), queryValues);
options.Events = new OpenIdConnectEvents() options.Events = new OpenIdConnectEvents()
{ {
OnRedirectToIdentityProvider = context => OnRedirectToAuthenticationEndpoint = context =>
{ {
context.ProtocolMessage.ClientId = queryValuesSetInEvent.ClientId; context.ProtocolMessage.ClientId = queryValuesSetInEvent.ClientId;
context.ProtocolMessage.RedirectUri = queryValuesSetInEvent.RedirectUri; context.ProtocolMessage.RedirectUri = queryValuesSetInEvent.RedirectUri;
@ -344,7 +368,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
{ {
app.UseCookieAuthentication(options => app.UseCookieAuthentication(options =>
{ {
options.AuthenticationScheme = OpenIdConnectDefaults.AuthenticationScheme; options.AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}); });
app.UseOpenIdConnectAuthentication(configureOptions); app.UseOpenIdConnectAuthentication(configureOptions);
app.Use(async (context, next) => app.Use(async (context, next) =>