#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:
parent
92d5e4ce77
commit
1c0768fb71
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,15 +6,15 @@ using Microsoft.IdentityModel.Protocols.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)
|
||||
{
|
||||
}
|
||||
|
||||
public string SecurityToken { get; set; }
|
||||
|
||||
public OpenIdConnectMessage ProtocolMessage { get; set; }
|
||||
|
||||
public OpenIdConnectTokenEndpointResponse TokenEndpointResponse { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -2,17 +2,20 @@
|
|||
// 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.Authentication;
|
||||
using Microsoft.IdentityModel.Protocols.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)
|
||||
{
|
||||
}
|
||||
|
||||
public OpenIdConnectMessage ProtocolMessage { get; set; }
|
||||
|
||||
public AuthenticationProperties Properties { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -10,20 +10,30 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
/// </summary>
|
||||
public interface IOpenIdConnectEvents
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoked when the authentication process completes.
|
||||
/// </summary>
|
||||
Task AuthenticationCompleted(AuthenticationCompletedContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed.
|
||||
/// </summary>
|
||||
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>
|
||||
/// Invoked after security token validation if an authorization code is present in the protocol message.
|
||||
/// </summary>
|
||||
Task AuthorizationCodeReceived(AuthorizationCodeReceivedContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked after "authorization code" is redeemed for tokens at the token endpoint.
|
||||
/// Invoked when an authorization response is received.
|
||||
/// </summary>
|
||||
Task AuthorizationCodeRedeemed(AuthorizationCodeRedeemedContext context);
|
||||
Task AuthorizationResponseReceived(AuthorizationResponseReceivedContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when a protocol message is first received.
|
||||
|
|
@ -31,18 +41,23 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
Task MessageReceived(MessageReceivedContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked to manipulate redirects to the identity provider for SignIn, SignOut, or Challenge.
|
||||
/// Invoked before redirecting to the identity provider to authenticate.
|
||||
/// </summary>
|
||||
Task RedirectToIdentityProvider(RedirectToIdentityProviderContext context);
|
||||
Task RedirectToAuthenticationEndpoint(RedirectContext context);
|
||||
|
||||
/// <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>
|
||||
Task SecurityTokenReceived(SecurityTokenReceivedContext context);
|
||||
Task RedirectToEndSessionEndpoint(RedirectContext context);
|
||||
|
||||
/// <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>
|
||||
Task SecurityTokenValidated(SecurityTokenValidatedContext context);
|
||||
Task TokenResponseReceived(TokenResponseReceivedContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when user information is retrieved from the UserInfoEndpoint.
|
||||
/// </summary>
|
||||
Task UserInformationReceived(UserInformationReceivedContext context);
|
||||
}
|
||||
}
|
||||
|
|
@ -11,20 +11,30 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
/// </summary>
|
||||
public class OpenIdConnectEvents : IOpenIdConnectEvents
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoked when the authentication process completes.
|
||||
/// </summary>
|
||||
public Func<AuthenticationCompletedContext, Task> OnAuthenticationCompleted { get; set; } = context => Task.FromResult(0);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed.
|
||||
/// </summary>
|
||||
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>
|
||||
/// Invoked after security token validation if an authorization code is present in the protocol message.
|
||||
/// </summary>
|
||||
public Func<AuthorizationCodeReceivedContext, Task> OnAuthorizationCodeReceived { get; set; } = context => Task.FromResult(0);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked after "authorization code" is redeemed for tokens at the token endpoint.
|
||||
/// Invoked when an authorization response is received.
|
||||
/// </summary>
|
||||
public Func<AuthorizationCodeRedeemedContext, Task> OnAuthorizationCodeRedeemed { get; set; } = context => Task.FromResult(0);
|
||||
public Func<AuthorizationResponseReceivedContext, Task> OnAuthorizationResponseReceived { get; set; } = context => Task.FromResult(0);
|
||||
|
||||
/// <summary>
|
||||
/// 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);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked to manipulate redirects to the identity provider for SignIn, SignOut, or Challenge.
|
||||
/// Invoked before redirecting to the identity provider to authenticate.
|
||||
/// </summary>
|
||||
public Func<RedirectToIdentityProviderContext, Task> OnRedirectToIdentityProvider { get; set; } = context => Task.FromResult(0);
|
||||
public Func<RedirectContext, Task> OnRedirectToAuthenticationEndpoint { get; set; } = context => Task.FromResult(0);
|
||||
|
||||
/// <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>
|
||||
public Func<SecurityTokenReceivedContext, Task> OnSecurityTokenReceived { get; set; } = context => Task.FromResult(0);
|
||||
public Func<RedirectContext, Task> OnRedirectToEndSessionEndpoint { get; set; } = context => Task.FromResult(0);
|
||||
|
||||
/// <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>
|
||||
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 AuthenticationValidated(AuthenticationValidatedContext context) => OnAuthenticationValidated(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 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -6,21 +6,16 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
/// <summary>
|
||||
/// This Context can be used to be informed when an 'AuthorizationCode' is redeemed for tokens at the token endpoint.
|
||||
/// </summary>
|
||||
public class AuthorizationCodeRedeemedContext : BaseControlContext<OpenIdConnectOptions>
|
||||
public class TokenResponseReceivedContext : BaseControlContext<OpenIdConnectOptions>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a <see cref="AuthorizationCodeRedeemedContext"/>
|
||||
/// Creates a <see cref="TokenResponseReceivedContext"/>
|
||||
/// </summary>
|
||||
public AuthorizationCodeRedeemedContext(HttpContext context, OpenIdConnectOptions options)
|
||||
public TokenResponseReceivedContext(HttpContext context, OpenIdConnectOptions options)
|
||||
: base(context, options)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the 'code'.
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="OpenIdConnectTokenEndpointResponse"/> that contains the tokens and json response received after redeeming the code at the token endpoint.
|
||||
/// </summary>
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -74,7 +74,6 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
var message = new OpenIdConnectMessage()
|
||||
{
|
||||
IssuerAddress = _configuration == null ? string.Empty : (_configuration.EndSessionEndpoint ?? string.Empty),
|
||||
RequestType = OpenIdConnectRequestType.LogoutRequest,
|
||||
};
|
||||
|
||||
// Set End_Session_Endpoint in order:
|
||||
|
|
@ -90,24 +89,24 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
message.PostLogoutRedirectUri = Options.PostLogoutRedirectUri;
|
||||
}
|
||||
|
||||
var redirectToIdentityProviderContext = new RedirectToIdentityProviderContext(Context, Options)
|
||||
var redirectContext = new RedirectContext(Context, Options)
|
||||
{
|
||||
ProtocolMessage = message
|
||||
};
|
||||
|
||||
await Options.Events.RedirectToIdentityProvider(redirectToIdentityProviderContext);
|
||||
if (redirectToIdentityProviderContext.HandledResponse)
|
||||
await Options.Events.RedirectToEndSessionEndpoint(redirectContext);
|
||||
if (redirectContext.HandledResponse)
|
||||
{
|
||||
Logger.LogVerbose(Resources.OIDCH_0034_RedirectToIdentityProviderContextHandledResponse);
|
||||
Logger.LogVerbose("RedirectToEndSessionEndpoint.HandledResponse");
|
||||
return;
|
||||
}
|
||||
else if (redirectToIdentityProviderContext.Skipped)
|
||||
else if (redirectContext.Skipped)
|
||||
{
|
||||
Logger.LogVerbose(Resources.OIDCH_0035_RedirectToIdentityProviderContextSkipped);
|
||||
Logger.LogVerbose("RedirectToEndSessionEndpoint.Skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
message = redirectToIdentityProviderContext.ProtocolMessage;
|
||||
message = redirectContext.ProtocolMessage;
|
||||
|
||||
if (Options.AuthenticationMethod == OpenIdConnectRedirectBehavior.RedirectGet)
|
||||
{
|
||||
|
|
@ -183,8 +182,6 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
ClientId = Options.ClientId,
|
||||
IssuerAddress = _configuration?.AuthorizationEndpoint ?? string.Empty,
|
||||
RedirectUri = Options.RedirectUri,
|
||||
// [brentschmaltz] - #215 this should be a property on RedirectToIdentityProviderContext not on the OIDCMessage.
|
||||
RequestType = OpenIdConnectRequestType.AuthenticationRequest,
|
||||
Resource = Options.Resource,
|
||||
ResponseType = Options.ResponseType,
|
||||
Scope = string.Join(" ", Options.Scope)
|
||||
|
|
@ -207,29 +204,29 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
|
||||
GenerateCorrelationId(properties);
|
||||
|
||||
var redirectToIdentityProviderContext = new RedirectToIdentityProviderContext(Context, Options)
|
||||
var redirectContext = new RedirectContext(Context, Options)
|
||||
{
|
||||
ProtocolMessage = message
|
||||
};
|
||||
|
||||
await Options.Events.RedirectToIdentityProvider(redirectToIdentityProviderContext);
|
||||
if (redirectToIdentityProviderContext.HandledResponse)
|
||||
await Options.Events.RedirectToAuthenticationEndpoint(redirectContext);
|
||||
if (redirectContext.HandledResponse)
|
||||
{
|
||||
Logger.LogVerbose(Resources.OIDCH_0034_RedirectToIdentityProviderContextHandledResponse);
|
||||
Logger.LogVerbose("RedirectToAuthenticationEndpoint.HandledResponse");
|
||||
return true;
|
||||
}
|
||||
else if (redirectToIdentityProviderContext.Skipped)
|
||||
else if (redirectContext.Skipped)
|
||||
{
|
||||
Logger.LogVerbose(Resources.OIDCH_0035_RedirectToIdentityProviderContextSkipped);
|
||||
Logger.LogVerbose("RedirectToAuthenticationEndpoint.Skipped");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(redirectToIdentityProviderContext.ProtocolMessage.State))
|
||||
{
|
||||
properties.Items[OpenIdConnectDefaults.UserstatePropertiesKey] = redirectToIdentityProviderContext.ProtocolMessage.State;
|
||||
}
|
||||
message = redirectContext.ProtocolMessage;
|
||||
|
||||
message = redirectToIdentityProviderContext.ProtocolMessage;
|
||||
if (!string.IsNullOrEmpty(message.State))
|
||||
{
|
||||
properties.Items[OpenIdConnectDefaults.UserstatePropertiesKey] = message.State;
|
||||
}
|
||||
|
||||
var redirectUriForCode = message.RedirectUri;
|
||||
if (string.IsNullOrEmpty(redirectUriForCode))
|
||||
|
|
@ -350,36 +347,35 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
{
|
||||
return null;
|
||||
}
|
||||
message = messageReceivedContext.ProtocolMessage;
|
||||
|
||||
var properties = new AuthenticationProperties();
|
||||
|
||||
// if state is missing, just log it
|
||||
// Fail if state is missing, it's required for the correlation id.
|
||||
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;
|
||||
properties.Items.TryGetValue(OpenIdConnectDefaults.UserstatePropertiesKey, out userstate);
|
||||
message.State = userstate;
|
||||
// if state exists and we failed to 'unprotect' this is not a message we should process.
|
||||
var properties = Options.StateDataFormat.Unprotect(Uri.UnescapeDataString(message.State));
|
||||
if (properties == null)
|
||||
{
|
||||
Logger.LogError(Resources.OIDCH_0005_MessageStateIsInvalid);
|
||||
return null;
|
||||
}
|
||||
|
||||
// if any of the error fields are set, throw error null
|
||||
if (!string.IsNullOrEmpty(message.Error))
|
||||
{
|
||||
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))
|
||||
{
|
||||
return null;
|
||||
|
|
@ -391,6 +387,26 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
_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))
|
||||
{
|
||||
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)
|
||||
{
|
||||
AuthenticationTicket ticket = null;
|
||||
JwtSecurityToken jwt = null;
|
||||
|
||||
OpenIdConnectTokenEndpointResponse tokenEndpointResponse = null;
|
||||
string idToken = null;
|
||||
var authorizationCodeReceivedContext = await RunAuthorizationCodeReceivedEventAsync(message, properties, ticket, jwt);
|
||||
if (authorizationCodeReceivedContext.HandledResponse)
|
||||
{
|
||||
|
|
@ -449,14 +464,15 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
{
|
||||
return null;
|
||||
}
|
||||
message = authorizationCodeReceivedContext.ProtocolMessage;
|
||||
var code = authorizationCodeReceivedContext.Code;
|
||||
|
||||
// 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);
|
||||
idToken = tokenEndpointResponse.Message.IdToken;
|
||||
var tokenEndpointResponse = await RedeemAuthorizationCodeAsync(code, authorizationCodeReceivedContext.RedirectUri);
|
||||
|
||||
var authorizationCodeRedeemedContext = await RunAuthorizationCodeRedeemedEventAsync(message, tokenEndpointResponse);
|
||||
var authorizationCodeRedeemedContext = await RunTokenResponseReceivedEventAsync(message, tokenEndpointResponse);
|
||||
if (authorizationCodeRedeemedContext.HandledResponse)
|
||||
{
|
||||
return authorizationCodeRedeemedContext.AuthenticationTicket;
|
||||
|
|
@ -466,63 +482,61 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
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].
|
||||
var validationParameters = Options.TokenValidationParameters.Clone();
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
Logger.LogDebug(Resources.OIDCH_0040_Sending_Request_UIEndpoint);
|
||||
ticket = await GetUserInformationAsync(properties, tokenEndpointResponse.Message, ticket);
|
||||
}
|
||||
|
||||
var securityTokenValidatedContext = await RunSecurityTokenValidatedEventAsync(message, ticket);
|
||||
if (securityTokenValidatedContext.HandledResponse)
|
||||
{
|
||||
return securityTokenValidatedContext.AuthenticationTicket;
|
||||
}
|
||||
else if (securityTokenValidatedContext.Skipped)
|
||||
{
|
||||
return null;
|
||||
ticket = await GetUserInformationAsync(tokenEndpointResponse.ProtocolMessage, ticket);
|
||||
}
|
||||
|
||||
return ticket;
|
||||
}
|
||||
|
||||
// Implicit Flow or Hybrid Flow
|
||||
private async Task<AuthenticationTicket> HandleIdTokenFlows(OpenIdConnectMessage message, AuthenticationProperties properties)
|
||||
{
|
||||
AuthenticationTicket ticket = null;
|
||||
Logger.LogDebug(Resources.OIDCH_0020_IdTokenReceived, message.IdToken);
|
||||
|
||||
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();
|
||||
ticket = ValidateToken(message.IdToken, message, properties, validationParameters, out jwt);
|
||||
var ticket = ValidateToken(message.IdToken, message, properties, validationParameters, out jwt);
|
||||
|
||||
await ValidateOpenIdConnectProtocolAsync(jwt, message);
|
||||
|
||||
var securityTokenValidatedContext = await RunSecurityTokenValidatedEventAsync(message, ticket);
|
||||
if (securityTokenValidatedContext.HandledResponse)
|
||||
var authenticationValidatedContext = await RunAuthenticationValidatedEventAsync(message, ticket, tokenEndpointResponse: null);
|
||||
if (authenticationValidatedContext.HandledResponse)
|
||||
{
|
||||
return securityTokenValidatedContext.AuthenticationTicket;
|
||||
return authenticationValidatedContext.AuthenticationTicket;
|
||||
}
|
||||
else if (securityTokenValidatedContext.Skipped)
|
||||
else if (authenticationValidatedContext.Skipped)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
message = authenticationValidatedContext.ProtocolMessage;
|
||||
ticket = authenticationValidatedContext.AuthenticationTicket;
|
||||
|
||||
// Hybrid Flow
|
||||
if (message.Code != null)
|
||||
{
|
||||
var authorizationCodeReceivedContext = await RunAuthorizationCodeReceivedEventAsync(message, properties, ticket, jwt);
|
||||
|
|
@ -534,6 +548,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
{
|
||||
return null;
|
||||
}
|
||||
ticket = authorizationCodeReceivedContext.AuthenticationTicket;
|
||||
}
|
||||
|
||||
return ticket;
|
||||
|
|
@ -568,17 +583,12 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
/// <summary>
|
||||
/// Goes to UserInfo endpoint to retrieve additional claims and add any unique claims to the given identity.
|
||||
/// </summary>
|
||||
/// <param name="properties">Authentication Properties</param>
|
||||
/// <param name="message">message that is being processed</param>
|
||||
/// <param name="ticket">authentication ticket with claims principal and identities</param>
|
||||
/// <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;
|
||||
if (_configuration != null)
|
||||
{
|
||||
userInfoEndpoint = _configuration.UserInfoEndpoint;
|
||||
}
|
||||
string userInfoEndpoint = _configuration?.UserInfoEndpoint;
|
||||
|
||||
if (string.IsNullOrEmpty(userInfoEndpoint))
|
||||
{
|
||||
|
|
@ -593,6 +603,18 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
var userInfoResponse = await responseMessage.Content.ReadAsStringAsync();
|
||||
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 subjectClaimType = identity.FindFirst(ClaimTypes.NameIdentifier);
|
||||
if (subjectClaimType == null)
|
||||
|
|
@ -846,68 +868,71 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
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);
|
||||
var authorizationCodeRedeemedContext = new AuthorizationCodeRedeemedContext(Context, Options)
|
||||
Logger.LogDebug("Token response received.");
|
||||
var tokenResponseReceivedContext = new TokenResponseReceivedContext(Context, Options)
|
||||
{
|
||||
Code = message.Code,
|
||||
ProtocolMessage = message,
|
||||
TokenEndpointResponse = tokenEndpointResponse
|
||||
};
|
||||
|
||||
await Options.Events.AuthorizationCodeRedeemed(authorizationCodeRedeemedContext);
|
||||
if (authorizationCodeRedeemedContext.HandledResponse)
|
||||
await Options.Events.TokenResponseReceived(tokenResponseReceivedContext);
|
||||
if (tokenResponseReceivedContext.HandledResponse)
|
||||
{
|
||||
Logger.LogVerbose(Resources.OIDCH_0043_AuthorizationCodeRedeemedContextHandledResponse);
|
||||
}
|
||||
else if (authorizationCodeRedeemedContext.Skipped)
|
||||
else if (tokenResponseReceivedContext.Skipped)
|
||||
{
|
||||
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 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)
|
||||
var authenticationValidatedContext = new AuthenticationValidatedContext(Context, Options)
|
||||
{
|
||||
AuthenticationTicket = ticket,
|
||||
ProtocolMessage = message
|
||||
ProtocolMessage = message,
|
||||
TokenEndpointResponse = tokenEndpointResponse,
|
||||
};
|
||||
|
||||
await Options.Events.SecurityTokenValidated(securityTokenValidatedContext);
|
||||
if (securityTokenValidatedContext.HandledResponse)
|
||||
await Options.Events.AuthenticationValidated(authenticationValidatedContext);
|
||||
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)
|
||||
|
|
@ -980,7 +1005,6 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
ticket.Properties.Items[OpenIdConnectSessionProperties.CheckSessionIFrame] = _configuration.CheckSessionIframe;
|
||||
}
|
||||
|
||||
// Rename?
|
||||
if (Options.UseTokenLifetime)
|
||||
{
|
||||
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>
|
||||
public override Task<bool> InvokeAsync()
|
||||
{
|
||||
return InvokeReplyPathAsync();
|
||||
return InvokeReturnPathAsync();
|
||||
}
|
||||
|
||||
private async Task<bool> InvokeReplyPathAsync()
|
||||
private async Task<bool> InvokeReturnPathAsync()
|
||||
{
|
||||
var ticket = await HandleAuthenticateOnceAsync();
|
||||
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)
|
||||
{
|
||||
await Request.HttpContext.Authentication.SignInAsync(Options.SignInScheme, ticket.Principal, ticket.Properties);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
// 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.IdentityModel.Protocols.OpenIdConnect;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
|
|
@ -15,7 +14,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
public OpenIdConnectTokenEndpointResponse(JObject jsonResponse)
|
||||
{
|
||||
JsonResponse = jsonResponse;
|
||||
Message = new OpenIdConnectMessage()
|
||||
ProtocolMessage = new OpenIdConnectMessage()
|
||||
{
|
||||
AccessToken = JsonResponse.Value<string>(OpenIdConnectParameterNames.AccessToken),
|
||||
IdToken = JsonResponse.Value<string>(OpenIdConnectParameterNames.IdToken),
|
||||
|
|
@ -27,7 +26,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
/// <summary>
|
||||
/// OpenIdConnect message that contains the id token and access tokens
|
||||
/// </summary>
|
||||
public OpenIdConnectMessage Message { get; set; }
|
||||
public OpenIdConnectMessage ProtocolMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Json response returned from the token endpoint
|
||||
|
|
|
|||
|
|
@ -186,38 +186,6 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
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>
|
||||
/// OIDCH_0036: Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute) returned 'false', redirectUri is: '{0}'.
|
||||
/// </summary>
|
||||
|
|
@ -426,38 +394,6 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
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>
|
||||
/// OIDCH_0010: Validated Security Token must be a JwtSecurityToken was: '{0}'.
|
||||
/// </summary>
|
||||
|
|
@ -490,38 +426,6 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
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>
|
||||
/// OIDCH_0014: AuthorizationCode received: '{0}'.
|
||||
/// </summary>
|
||||
|
|
@ -666,22 +570,6 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
|
|||
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>
|
||||
/// OIDCH_0043: AuthorizationCodeRedeemedContext.HandledResponse
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -150,12 +150,6 @@
|
|||
<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>
|
||||
</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">
|
||||
<value>OIDCH_0036: Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute) returned 'false', redirectUri is: '{0}'.</value>
|
||||
</data>
|
||||
|
|
@ -195,24 +189,12 @@
|
|||
<data name="OIDCH_0007_UpdatingConfiguration" xml:space="preserve">
|
||||
<value>OIDCH_0007: Updating configuration</value>
|
||||
</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">
|
||||
<value>OIDCH_0010: Validated Security Token must be a JwtSecurityToken was: '{0}'.</value>
|
||||
</data>
|
||||
<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>
|
||||
</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">
|
||||
<value>OIDCH_0014: AuthorizationCode received: '{0}'.</value>
|
||||
</data>
|
||||
|
|
@ -240,9 +222,6 @@
|
|||
<data name="OIDCH_0041_Subject_Claim_Not_Found" xml:space="preserve">
|
||||
<value>OIDCH_0041: Subject claim not found in {0}.</value>
|
||||
</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">
|
||||
<value>OIDCH_0043: AuthorizationCodeRedeemedContext.HandledResponse</value>
|
||||
</data>
|
||||
|
|
|
|||
|
|
@ -5,13 +5,11 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Http.Features;
|
||||
using Microsoft.AspNet.Http.Features.Authentication;
|
||||
using Microsoft.AspNet.Http.Internal;
|
||||
using Microsoft.Framework.Logging;
|
||||
using Microsoft.Framework.Primitives;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Authentication
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
|
|||
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;
|
||||
if (claimsIdentity == null)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IdentityModel.Tokens;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Linq;
|
||||
|
|
@ -19,7 +18,6 @@ using Microsoft.Framework.Logging;
|
|||
using Microsoft.Framework.OptionsModel;
|
||||
using Microsoft.Framework.WebEncoders;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
|
||||
|
|
@ -56,7 +54,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
|
|||
Assert.False(logger.IsEnabled(LogLevel.Warning));
|
||||
}
|
||||
|
||||
[Theory, MemberData("AuthenticateCoreStateDataSet")]
|
||||
[Theory, MemberData(nameof(AuthenticateCoreStateDataSet))]
|
||||
public async Task AuthenticateCoreState(Action<OpenIdConnectOptions> action, OpenIdConnectMessage message)
|
||||
{
|
||||
var handler = new OpenIdConnectHandlerForTestingAuthenticate();
|
||||
|
|
@ -103,7 +101,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
|
|||
options.StateDataFormat = new AuthenticationPropertiesFormaterKeyValue();
|
||||
options.Events = new OpenIdConnectEvents()
|
||||
{
|
||||
OnAuthorizationCodeRedeemed = context =>
|
||||
OnTokenResponseReceived = context =>
|
||||
{
|
||||
context.HandleResponse();
|
||||
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)
|
||||
{
|
||||
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();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,28 +106,47 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests RedirectToIdentityProviderContext replaces the OpenIdConnectMesssage correctly.
|
||||
/// Tests RedirectForAuthenticationContext replaces the OpenIdConnectMesssage correctly.
|
||||
/// </summary>
|
||||
/// <returns>Task</returns>
|
||||
[Theory]
|
||||
[InlineData(Challenge, OpenIdConnectRequestType.AuthenticationRequest)]
|
||||
[InlineData(Signout, OpenIdConnectRequestType.LogoutRequest)]
|
||||
public async Task ChallengeSettingMessage(string challenge, OpenIdConnectRequestType requestType)
|
||||
[Fact]
|
||||
public async Task ChallengeSettingMessage()
|
||||
{
|
||||
var configuration = new OpenIdConnectConfiguration
|
||||
{
|
||||
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
|
||||
};
|
||||
|
||||
var queryValues = new ExpectedQueryValues(DefaultAuthority, configuration)
|
||||
{
|
||||
RequestType = requestType
|
||||
RequestType = OpenIdConnectRequestType.LogoutRequest
|
||||
};
|
||||
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);
|
||||
queryValues.CheckValues(transaction.Response.Headers.Location.AbsoluteUri, new string[] {});
|
||||
queryValues.CheckValues(transaction.Response.Headers.Location.AbsoluteUri, new string[] { });
|
||||
}
|
||||
|
||||
private static void SetProtocolMessageOptions(OpenIdConnectOptions options)
|
||||
|
|
@ -138,7 +157,12 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
|
|||
options.AutomaticAuthentication = true;
|
||||
options.Events = new OpenIdConnectEvents()
|
||||
{
|
||||
OnRedirectToIdentityProvider = (context) =>
|
||||
OnRedirectToAuthenticationEndpoint = (context) =>
|
||||
{
|
||||
context.ProtocolMessage = mockOpenIdConnectMessage.Object;
|
||||
return Task.FromResult<object>(null);
|
||||
},
|
||||
OnRedirectToEndSessionEndpoint = (context) =>
|
||||
{
|
||||
context.ProtocolMessage = mockOpenIdConnectMessage.Object;
|
||||
return Task.FromResult<object>(null);
|
||||
|
|
@ -170,7 +194,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
|
|||
options.AutomaticAuthentication = challenge.Equals(ChallengeWithOutContext);
|
||||
options.Events = new OpenIdConnectEvents()
|
||||
{
|
||||
OnRedirectToIdentityProvider = context =>
|
||||
OnRedirectToAuthenticationEndpoint = context =>
|
||||
{
|
||||
context.ProtocolMessage.State = userState;
|
||||
return Task.FromResult<object>(null);
|
||||
|
|
@ -221,7 +245,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
|
|||
SetOptions(options, DefaultParameters(), queryValues);
|
||||
options.Events = new OpenIdConnectEvents()
|
||||
{
|
||||
OnRedirectToIdentityProvider = context =>
|
||||
OnRedirectToAuthenticationEndpoint = context =>
|
||||
{
|
||||
context.ProtocolMessage.ClientId = queryValuesSetInEvent.ClientId;
|
||||
context.ProtocolMessage.RedirectUri = queryValuesSetInEvent.RedirectUri;
|
||||
|
|
@ -344,7 +368,7 @@ namespace Microsoft.AspNet.Authentication.Tests.OpenIdConnect
|
|||
{
|
||||
app.UseCookieAuthentication(options =>
|
||||
{
|
||||
options.AuthenticationScheme = OpenIdConnectDefaults.AuthenticationScheme;
|
||||
options.AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
});
|
||||
app.UseOpenIdConnectAuthentication(configureOptions);
|
||||
app.Use(async (context, next) =>
|
||||
|
|
|
|||
Loading…
Reference in New Issue