public async static Task DefaultRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context) { // This ensures that the address used for sign in and sign out is picked up dynamically from the request // this allows you to deploy your app (to Azure Web Sites, for example)without having to change settings // Remember that the base URL of the address used here must be provisioned in Azure AD beforehand. string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase; context.ProtocolMessage.RedirectUri = appBaseUrl + "/"; context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl; await Task.Yield(); }
private static Task RedirectToIdentityProvider( RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context) { // This ensures that the address used for sign in and sign out is picked up dynamically from the request // this allows you to deploy your app (to Azure Web Sites, for example) without having to change settings // Remember that the base URL of the address used here must be provisioned in Azure AD beforehand. var appBaseUrl = $"{context.Request.Scheme}://{context.Request.Host}{context.Request.PathBase}"; context.ProtocolMessage.RedirectUri = appBaseUrl; context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl; return Task.FromResult(0); }
private static Task RedirectToIdentityProvider( RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> n) { if (n.ProtocolMessage.RequestType != OpenIdConnectRequestType.LogoutRequest) return Task.FromResult(true); var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token").Value; n.ProtocolMessage.IdTokenHint = idTokenHint; return Task.FromResult(true); }
private Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification) { // If the user is trying to sign up, we'll force the consent screen to be shown & pre-populate the sign-in name. if (notification.Request.Path.Value.ToLower() == "/account/signup/aad") { notification.ProtocolMessage.Prompt = "consent"; string login_hint = notification.OwinContext.Authentication.AuthenticationResponseChallenge.Properties.Dictionary["login_hint"]; notification.ProtocolMessage.LoginHint = login_hint; } return Task.FromResult(0); }
internal static async Task RedirectToIdentityProvider (RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context) { notificationsFired.Add(nameof(RedirectToIdentityProvider)); if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { context.ProtocolMessage.PostLogoutRedirectUri = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase + new PathString("/Account/Login"); } await Task.FromResult(0); }
// This notification can be used to manipulate the OIDC request before it is sent. Here we use it to send the correct policy. private async Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification) { PolicyConfigurationManager mgr = notification.Options.ConfigurationManager as PolicyConfigurationManager; if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, notification.OwinContext.Authentication.AuthenticationResponseRevoke.Properties.Dictionary[Startup.PolicyKey]); notification.ProtocolMessage.IssuerAddress = config.EndSessionEndpoint; } else { OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, notification.OwinContext.Authentication.AuthenticationResponseChallenge.Properties.Dictionary[Startup.PolicyKey]); notification.ProtocolMessage.IssuerAddress = config.AuthorizationEndpoint; } }
private Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification) { if (notification.Request.Path.Value.ToLower() == "/account/signup/aad") { notification.ProtocolMessage.Prompt = "consent"; string login_hint = notification.OwinContext.Authentication.AuthenticationResponseChallenge.Properties.Dictionary["login_hint"]; notification.ProtocolMessage.LoginHint = login_hint; } // Override the post signout redirect URI to be the URL of the app determined on the fly. // That way sign out works without config change regardless if running locally or running in the cloud. if (notification.Request.Path.Value.ToLower() == "/account/signout") notification.ProtocolMessage.PostLogoutRedirectUri = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority); // Explicitly add the redirectUri to the request. // This allows multiple redirect URIs to be registered in Azure AD, one for running locally and one for when running in the cloud. notification.ProtocolMessage.RedirectUri = (new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority))).ToString(); return Task.FromResult(0); }
protected override async Task ApplyResponseGrantAsync() { AuthenticationResponseRevoke signout = Helper.LookupSignOut(Options.AuthenticationType, Options.AuthenticationMode); if (signout != null) { AuthenticationProperties properties = signout.Properties; // Enable Per-Policy Metadata Retreival string policy; if (properties.Dictionary.TryGetValue(PolicyParameter, out policy)) { B2CConfigurationManager mgr = Options.ConfigurationManager as B2CConfigurationManager; _configuration = await mgr.GetConfigurationAsync(Context.Request.CallCancelled, policy); } else { throw new Exception("For B2C, you must pass a policy parameter in every sign out request."); } OpenIdConnectMessage openIdConnectMessage = new OpenIdConnectMessage() { IssuerAddress = _configuration.EndSessionEndpoint ?? string.Empty, RequestType = OpenIdConnectRequestType.LogoutRequest, }; string redirect = string.Empty; if (properties != null && !string.IsNullOrEmpty(properties.RedirectUri)) { openIdConnectMessage.PostLogoutRedirectUri = properties.RedirectUri; redirect = properties.RedirectUri; } else if (!string.IsNullOrWhiteSpace(Options.PostLogoutRedirectUri)) { openIdConnectMessage.PostLogoutRedirectUri = Options.PostLogoutRedirectUri; redirect = Options.RedirectUri; } if (string.IsNullOrWhiteSpace(openIdConnectMessage.PostLogoutRedirectUri)) { throw new Exception("For B2C, the PostLogoutRedirectUri is required."); } if (string.IsNullOrWhiteSpace(redirect)) { throw new Exception("For B2C, the RedirectUri is required."); } var notification = new RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>(Context, Options) { ProtocolMessage = openIdConnectMessage }; await Options.Notifications.RedirectToIdentityProvider(notification); if (!notification.HandledResponse) { string redirectUri = notification.ProtocolMessage.CreateLogoutRequestUrl(); redirectUri = redirectUri + "&" + OpenIdConnectParameterNames.RedirectUri + "=" + HttpUtility.UrlEncode(redirect) + "&" + OpenIdConnectParameterNames.ClientId + "=" + Options.ClientId; if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { _logger.WriteWarning("The logout redirect URI is malformed: " + redirectUri); } Response.Redirect(redirectUri); } } }
protected override async Task ApplyResponseChallengeAsync() { if (Response.StatusCode == 401) { AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); if (challenge == null) { return; } AuthenticationProperties properties = challenge.Properties; if (string.IsNullOrEmpty(properties.RedirectUri)) { properties.RedirectUri = CurrentUri; } if (!string.IsNullOrWhiteSpace(Options.RedirectUri)) { properties.Dictionary.Add(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey, Options.RedirectUri); } // Enable Per-Policy Metadata Retreival string policy; if (properties.Dictionary.TryGetValue(PolicyParameter, out policy)) { B2CConfigurationManager mgr = Options.ConfigurationManager as B2CConfigurationManager; _configuration = await mgr.GetConfigurationAsync(Context.Request.CallCancelled, policy); } else { throw new Exception("For B2C, you must pass a policy parameter in every challenge."); return; } OpenIdConnectMessage openIdConnectMessage = new OpenIdConnectMessage { ClientId = Options.ClientId, IssuerAddress = _configuration.AuthorizationEndpoint ?? string.Empty, RedirectUri = Options.RedirectUri, RequestType = OpenIdConnectRequestType.AuthenticationRequest, Resource = Options.Resource, ResponseMode = OpenIdConnectResponseModes.FormPost, ResponseType = Options.ResponseType, Scope = Options.Scope, State = AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(Options.StateDataFormat.Protect(properties)), }; if (Options.ProtocolValidator.RequireNonce) { AddNonceToMessage(openIdConnectMessage); } var notification = new RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>(Context, Options) { ProtocolMessage = openIdConnectMessage }; await Options.Notifications.RedirectToIdentityProvider(notification); if (!notification.HandledResponse) { string redirectUri = notification.ProtocolMessage.CreateAuthenticationRequestUrl(); if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { _logger.WriteWarning("The authenticate redirect URI is malformed: " + redirectUri); } Response.Redirect(redirectUri); } } return; }
/* * On each call to Azure AD B2C, check if a policy (e.g. the profile edit or password reset policy) has been specified in the OWIN context. * If so, use that policy when making the call. Also, don't request a code (since it won't be needed). */ private Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification <OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification) { if (notification.Request.Path.Value == "/Account/SignUp") { var policy = notification.OwinContext.Get <string>("Policy"); if (!string.IsNullOrEmpty(policy) && !policy.Equals(Globals.DefaultPolicy)) { //notification.ProtocolMessage.Scope = OpenIdConnectScope.OpenId; //notification.ProtocolMessage.ResponseType = OpenIdConnectResponseType.IdToken; notification.ProtocolMessage.IssuerAddress = notification.ProtocolMessage.IssuerAddress.ToLower().Replace(Globals.DefaultPolicy.ToLower(), policy.ToLower()); } } else if (notification.Request.Path.Value == "/Account/SignIn") { var policy = notification.OwinContext.Get <string>("Policy"); if (!string.IsNullOrEmpty(policy) && !policy.Equals(Globals.DefaultPolicy)) { //notification.ProtocolMessage.Scope = OpenIdConnectScope.OpenId; //notification.ProtocolMessage.ResponseType = OpenIdConnectResponseType.IdToken; notification.ProtocolMessage.IssuerAddress = notification.ProtocolMessage.IssuerAddress.ToLower().Replace(Globals.DefaultPolicy.ToLower(), policy.ToLower()); } } else if (notification.Request.Path.Value == "/Account/EditProfile") { var policy = notification.OwinContext.Get <string>("Policy"); if (!string.IsNullOrEmpty(policy) && !policy.Equals(Globals.DefaultPolicy)) { //notification.ProtocolMessage.Scope = OpenIdConnectScope.OpenId; //notification.ProtocolMessage.ResponseType = OpenIdConnectResponseType.IdToken; notification.ProtocolMessage.IssuerAddress = notification.ProtocolMessage.IssuerAddress.ToLower().Replace(Globals.DefaultPolicy.ToLower(), policy.ToLower()); } } else if (notification.Request.Path.Value == "/Account/ResetPassword") { var policy = notification.OwinContext.Get <string>("Policy"); if (!string.IsNullOrEmpty(policy) && !policy.Equals(Globals.DefaultPolicy)) { //notification.ProtocolMessage.Scope = OpenIdConnectScope.OpenId; //notification.ProtocolMessage.ResponseType = OpenIdConnectResponseType.IdToken; notification.ProtocolMessage.IssuerAddress = notification.ProtocolMessage.IssuerAddress.ToLower().Replace(Globals.DefaultPolicy.ToLower(), policy.ToLower()); } } else if (notification.Request.Path.Value == "/Account/SignOut") { var policy = notification.OwinContext.Get <string>("Policy"); if (!string.IsNullOrEmpty(policy) && !policy.Equals(Globals.DefaultPolicy)) { //notification.ProtocolMessage.Scope = OpenIdConnectScope.OpenId; //notification.ProtocolMessage.ResponseType = OpenIdConnectResponseType.IdToken; notification.ProtocolMessage.IssuerAddress = notification.ProtocolMessage.IssuerAddress.ToLower().Replace(Globals.DefaultPolicy.ToLower(), policy.ToLower()); } } else { notification.Response.StatusCode = 401; notification.Response.Redirect("/Home/Error?message=Access Denied"); notification.HandleResponse(); } return(Task.FromResult(0)); }
/// <summary> /// Handles Challenge /// </summary> /// <returns></returns> protected override async Task ApplyResponseChallengeAsync() { if (Response.StatusCode == 401) { AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); if (challenge == null) { return; } string baseUri = Request.Scheme + Uri.SchemeDelimiter + Request.Host + Request.PathBase; string currentUri = baseUri + Request.Path + Request.QueryString; // Save the original challenge URI so we can redirect back to it when we're done. AuthenticationProperties properties = challenge.Properties; if (string.IsNullOrEmpty(properties.RedirectUri)) { properties.RedirectUri = currentUri; } WsFederationMessage wsFederationMessage = new WsFederationMessage() { IssuerAddress = Options.IssuerAddress ?? string.Empty, Wtrealm = Options.Wtrealm, Wctx = WsFederationAuthenticationDefaults.WctxKey + "=" + Uri.EscapeDataString(Options.StateDataFormat.Protect(properties)), }; if (!string.IsNullOrWhiteSpace(Options.Wreply)) { wsFederationMessage.Wreply = Options.Wreply; } if (Options.Notifications != null && Options.Notifications.RedirectToIdentityProvider != null) { RedirectToIdentityProviderNotification <WsFederationMessage> notification = new RedirectToIdentityProviderNotification <WsFederationMessage> { ProtocolMessage = wsFederationMessage }; await Options.Notifications.RedirectToIdentityProvider(notification); if (notification.Cancel) { return; } } string redirect = wsFederationMessage.CreateSignInQueryString(); if (!Uri.IsWellFormedUriString(redirect, UriKind.Absolute)) { _logger.WriteError(string.Format(CultureInfo.InvariantCulture, "The WsFederation sign-in redirect uri is not well formed: '{0}'", redirect)); return; } Response.Redirect(redirect); } return; }
/// <summary> /// Handles SignIn /// </summary> /// <returns></returns> protected override async Task ApplyResponseChallengeAsync() { if (Response.StatusCode == 401) { AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); if (challenge == null) { return; } // order for redirect_uri // 1. challenge.Properties.RedirectUri // 2. CurrentUri AuthenticationProperties properties = challenge.Properties; if (string.IsNullOrEmpty(properties.RedirectUri)) { properties.RedirectUri = CurrentUri; } // this value will be passed to the AuthorizationCodeRedeemedNotification if (!string.IsNullOrWhiteSpace(Options.RedirectUri)) { properties.Dictionary.Add(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey, Options.RedirectUri); } if (_configuration == null) { _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.Request.CallCancelled); } OpenIdConnectMessage openIdConnectMessage = new OpenIdConnectMessage { ClientId = Options.ClientId, IssuerAddress = _configuration.AuthorizationEndpoint ?? string.Empty, RedirectUri = Options.RedirectUri, RequestType = OpenIdConnectRequestType.Authentication, Resource = Options.Resource, ResponseMode = OpenIdConnectResponseMode.FormPost, ResponseType = Options.ResponseType, Scope = Options.Scope, State = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(Options.StateDataFormat.Protect(properties)), }; if (Options.ProtocolValidator.RequireNonce) { AddNonceToMessage(openIdConnectMessage); } var notification = new RedirectToIdentityProviderNotification <OpenIdConnectMessage, OpenIdConnectAuthenticationOptions >(Context, Options) { ProtocolMessage = openIdConnectMessage }; await Options.Notifications.RedirectToIdentityProvider(notification); if (!notification.HandledResponse) { string redirectUri = notification.ProtocolMessage.CreateAuthenticationRequestUrl(); if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { _logger.WriteWarning("The authenticate redirect URI is malformed: " + redirectUri); } Response.Redirect(redirectUri); } } return; }
/// <summary> /// Responds to a 401 Challenge. Sends an OpenIdConnect message to the 'identity authority' to obtain an identity. /// </summary> /// <returns></returns> /// <remarks>Uses log id's OIDCH-0026 - OIDCH-0050, next num: 37</remarks> protected override async Task <bool> HandleUnauthorizedAsync([NotNull] ChallengeContext context) { Logger.LogDebug(Resources.OIDCH_0026_ApplyResponseChallengeAsync, this.GetType()); // order for local RedirectUri // 1. challenge.Properties.RedirectUri // 2. CurrentUri if Options.DefaultToCurrentUriOnRedirect is true) AuthenticationProperties properties = new AuthenticationProperties(context.Properties); if (!string.IsNullOrEmpty(properties.RedirectUri)) { Logger.LogDebug(Resources.OIDCH_0030_Using_Properties_RedirectUri, properties.RedirectUri); } else if (Options.DefaultToCurrentUriOnRedirect) { Logger.LogDebug(Resources.OIDCH_0032_UsingCurrentUriRedirectUri, CurrentUri); properties.RedirectUri = CurrentUri; } if (_configuration == null && Options.ConfigurationManager != null) { _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted); } var message = new OpenIdConnectMessage { ClientId = Options.ClientId, IssuerAddress = _configuration?.AuthorizationEndpoint ?? string.Empty, RedirectUri = Options.RedirectUri, // [brentschmaltz] - #215 this should be a property on RedirectToIdentityProviderNotification not on the OIDCMessage. RequestType = OpenIdConnectRequestType.AuthenticationRequest, Resource = Options.Resource, ResponseType = Options.ResponseType, Scope = Options.Scope }; // Omitting the response_mode parameter when it already corresponds to the default // response_mode used for the specified response_type is recommended by the specifications. // See http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseModes if (!string.Equals(Options.ResponseType, OpenIdConnectResponseTypes.Code, StringComparison.Ordinal) || !string.Equals(Options.ResponseMode, OpenIdConnectResponseModes.Query, StringComparison.Ordinal)) { message.ResponseMode = Options.ResponseMode; } if (Options.ProtocolValidator.RequireNonce) { message.Nonce = Options.ProtocolValidator.GenerateNonce(); if (Options.CacheNonces) { if (await Options.NonceCache.GetAsync(message.Nonce) != null) { Logger.LogError(Resources.OIDCH_0033_NonceAlreadyExists, message.Nonce); throw new OpenIdConnectProtocolException(string.Format(CultureInfo.InvariantCulture, Resources.OIDCH_0033_NonceAlreadyExists, message.Nonce)); } await Options.NonceCache.SetAsync(message.Nonce, new byte[0], new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = Options.ProtocolValidator.NonceLifetime }); } else { WriteNonceCookie(message.Nonce); } } if (Options.Notifications.RedirectToIdentityProvider != null) { var redirectToIdentityProviderNotification = new RedirectToIdentityProviderNotification <OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>(Context, Options) { ProtocolMessage = message }; await Options.Notifications.RedirectToIdentityProvider(redirectToIdentityProviderNotification); if (redirectToIdentityProviderNotification.HandledResponse) { Logger.LogVerbose(Resources.OIDCH_0034_RedirectToIdentityProviderNotificationHandledResponse); return(true); } else if (redirectToIdentityProviderNotification.Skipped) { Logger.LogVerbose(Resources.OIDCH_0035_RedirectToIdentityProviderNotificationSkipped); return(false); } if (!string.IsNullOrEmpty(redirectToIdentityProviderNotification.ProtocolMessage.State)) { properties.Items[OpenIdConnectAuthenticationDefaults.UserstatePropertiesKey] = redirectToIdentityProviderNotification.ProtocolMessage.State; } message = redirectToIdentityProviderNotification.ProtocolMessage; } var redirectUriForCode = message.RedirectUri; if (string.IsNullOrEmpty(redirectUriForCode)) { Logger.LogDebug(Resources.OIDCH_0031_Using_Options_RedirectUri, Options.RedirectUri); redirectUriForCode = Options.RedirectUri; } if (!string.IsNullOrEmpty(redirectUriForCode)) { // When redeeming a 'code' for an AccessToken, this value is needed properties.Items.Add(OpenIdConnectAuthenticationDefaults.RedirectUriForCodePropertiesKey, redirectUriForCode); } message.State = Options.StateDataFormat.Protect(properties); var redirectUri = message.CreateAuthenticationRequestUrl(); if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { Logger.LogWarning(Resources.OIDCH_0036_UriIsNotWellFormed, redirectUri); } Response.Redirect(redirectUri); return(true); }
protected override async Task ApplyResponseGrantAsync() { AuthenticationResponseRevoke signout = Helper.LookupSignOut(Options.AuthenticationType, Options.AuthenticationMode); if (signout != null) { AuthenticationProperties properties = signout.Properties; // Enable Per-Policy Metadata Retreival string policy; if (properties.Dictionary.TryGetValue(PolicyParameter, out policy)) { B2CConfigurationManager mgr = Options.ConfigurationManager as B2CConfigurationManager; _configuration = await mgr.GetConfigurationAsync(Context.Request.CallCancelled, policy); } else { throw new Exception("For B2C, you must pass a policy parameter in every sign out request."); } OpenIdConnectMessage openIdConnectMessage = new OpenIdConnectMessage() { IssuerAddress = _configuration.EndSessionEndpoint ?? string.Empty, RequestType = OpenIdConnectRequestType.LogoutRequest, }; string redirect = string.Empty; if (properties != null && !string.IsNullOrEmpty(properties.RedirectUri)) { openIdConnectMessage.PostLogoutRedirectUri = properties.RedirectUri; redirect = properties.RedirectUri; } else if (!string.IsNullOrWhiteSpace(Options.PostLogoutRedirectUri)) { openIdConnectMessage.PostLogoutRedirectUri = Options.PostLogoutRedirectUri; redirect = Options.RedirectUri; } if (string.IsNullOrWhiteSpace(openIdConnectMessage.PostLogoutRedirectUri)) { throw new Exception("For B2C, the PostLogoutRedirectUri is required."); } if (string.IsNullOrWhiteSpace(redirect)) { throw new Exception("For B2C, the RedirectUri is required."); } var notification = new RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>(Context, Options) { ProtocolMessage = openIdConnectMessage }; await Options.Notifications.RedirectToIdentityProvider(notification); if (!notification.HandledResponse) { string redirectUri = notification.ProtocolMessage.CreateLogoutRequestUrl(); redirectUri = redirectUri + "&" + OpenIdConnectParameterNames.RedirectUri + "=" + HttpUtility.UrlEncode(redirect) + "&" + OpenIdConnectParameterNames.ClientId + "=" + Options.ClientId; if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { _logger.WriteWarning("The logout redirect URI is malformed: " + redirectUri); } Response.Redirect(redirectUri); } } }
protected override async Task ApplyResponseChallengeAsync() { if (Response.StatusCode == 401) { AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); if (challenge == null) { return; } AuthenticationProperties properties = challenge.Properties; if (string.IsNullOrEmpty(properties.RedirectUri)) { properties.RedirectUri = CurrentUri; } if (!string.IsNullOrWhiteSpace(Options.RedirectUri)) { properties.Dictionary.Add(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey, Options.RedirectUri); } // Enable Per-Policy Metadata Retreival string policy; if (properties.Dictionary.TryGetValue(PolicyParameter, out policy)) { B2CConfigurationManager mgr = Options.ConfigurationManager as B2CConfigurationManager; _configuration = await mgr.GetConfigurationAsync(Context.Request.CallCancelled, policy); } else { throw new Exception("For B2C, you must pass a policy parameter in every challenge."); } OpenIdConnectMessage openIdConnectMessage = new OpenIdConnectMessage { ClientId = Options.ClientId, IssuerAddress = _configuration.AuthorizationEndpoint ?? string.Empty, RedirectUri = Options.RedirectUri, RequestType = OpenIdConnectRequestType.AuthenticationRequest, Resource = Options.Resource, ResponseMode = OpenIdConnectResponseModes.FormPost, ResponseType = Options.ResponseType, Scope = Options.Scope, State = AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(Options.StateDataFormat.Protect(properties)), }; if (Options.ProtocolValidator.RequireNonce) { AddNonceToMessage(openIdConnectMessage); } var notification = new RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>(Context, Options) { ProtocolMessage = openIdConnectMessage }; await Options.Notifications.RedirectToIdentityProvider(notification); if (!notification.HandledResponse) { string redirectUri = notification.ProtocolMessage.CreateAuthenticationRequestUrl(); if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { _logger.WriteWarning("The authenticate redirect URI is malformed: " + redirectUri); } Response.Redirect(redirectUri); } } return; }
/// <summary> /// Handles Challenge /// </summary> /// <returns></returns> protected override async Task ApplyResponseChallengeAsync() { if (Response.StatusCode != 401) { return; } AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); if (challenge == null) { return; } if (_configuration == null) { _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.Request.CallCancelled); } string baseUri = Request.Scheme + Uri.SchemeDelimiter + Request.Host + Request.PathBase; string currentUri = baseUri + Request.Path + Request.QueryString; // Save the original challenge URI so we can redirect back to it when we're done. AuthenticationProperties properties = challenge.Properties; if (string.IsNullOrEmpty(properties.RedirectUri)) { properties.RedirectUri = currentUri; } WsFederationMessage wsFederationMessage = new WsFederationMessage() { IssuerAddress = _configuration.TokenEndpoint ?? string.Empty, Wtrealm = Options.Wtrealm, Wctx = WsFederationAuthenticationDefaults.WctxKey + "=" + Uri.EscapeDataString(Options.StateDataFormat.Protect(properties)), Wa = WsFederationConstants.WsFederationActions.SignIn, }; if (!string.IsNullOrWhiteSpace(Options.Wreply)) { wsFederationMessage.Wreply = Options.Wreply; } var notification = new RedirectToIdentityProviderNotification <WsFederationMessage, WsFederationAuthenticationOptions>(Context, Options) { ProtocolMessage = wsFederationMessage }; await Options.Notifications.RedirectToIdentityProvider(notification); if (!notification.HandledResponse) { string redirectUri = notification.ProtocolMessage.CreateSignInUrl(); if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { _logger.WriteWarning("The sign-in redirect URI is malformed: " + redirectUri); } Response.Redirect(redirectUri); } }
/// <summary> /// Handles SignIn /// </summary> /// <returns></returns> protected override async Task ApplyResponseChallengeAsync() { if (Response.StatusCode == 401) { AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode); if (challenge == null) { return; } // order for redirect_uri // 1. challenge.Properties.RedirectUri // 2. CurrentUri AuthenticationProperties properties = challenge.Properties; if (string.IsNullOrEmpty(properties.RedirectUri)) { properties.RedirectUri = CurrentUri; } // this value will be passed to the AuthorizationCodeReceivedNotification if (!string.IsNullOrWhiteSpace(Options.RedirectUri)) { properties.Dictionary.Add(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey, Options.RedirectUri); } if (_configuration == null) { _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.Request.CallCancelled); } OpenIdConnectMessage openIdConnectMessage = new OpenIdConnectMessage { ClientId = Options.ClientId, IssuerAddress = _configuration.AuthorizationEndpoint ?? string.Empty, RedirectUri = Options.RedirectUri, RequestType = OpenIdConnectRequestType.Authentication, Resource = Options.Resource, ResponseType = Options.ResponseType, Scope = Options.Scope, State = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(Options.StateDataFormat.Protect(properties)), }; // Omitting the response_mode parameter when it already corresponds to the default // response_mode used for the specified response_type is recommended by the specifications. // See http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseModes if (!string.Equals(Options.ResponseType, OpenIdConnectResponseType.Code, StringComparison.Ordinal) || !string.Equals(Options.ResponseMode, OpenIdConnectResponseMode.Query, StringComparison.Ordinal)) { openIdConnectMessage.ResponseMode = Options.ResponseMode; } if (Options.ProtocolValidator.RequireNonce) { AddNonceToMessage(openIdConnectMessage); } var notification = new RedirectToIdentityProviderNotification <OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>(Context, Options) { ProtocolMessage = openIdConnectMessage }; await Options.Notifications.RedirectToIdentityProvider(notification); if (!notification.HandledResponse) { string redirectUri = notification.ProtocolMessage.CreateAuthenticationRequestUrl(); if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { _logger.WriteWarning("The authenticate redirect URI is malformed: " + redirectUri); } Response.Redirect(redirectUri); } } return; }
/// <summary> /// Responds to a 401 Challenge. Sends an OpenIdConnect message to the 'identity authority' to obtain an identity. /// </summary> /// <returns></returns> protected override async Task ApplyResponseChallengeAsync() { if (Response.StatusCode != 401) { return; } // Active middleware should redirect on 401 even if there wasn't an explicit challenge. if (ChallengeContext == null && Options.AuthenticationMode == AuthenticationMode.Passive) { return; } // order for redirect_uri // 1. challenge.Properties.RedirectUri // 2. CurrentUri AuthenticationProperties properties; if (ChallengeContext == null) { properties = new AuthenticationProperties(); } else { properties = new AuthenticationProperties(ChallengeContext.Properties); } if (string.IsNullOrEmpty(properties.RedirectUri)) { properties.RedirectUri = CurrentUri; } // this value will be passed to the AuthorizationCodeReceivedNotification if (!string.IsNullOrWhiteSpace(Options.RedirectUri)) { properties.Dictionary.Add(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey, Options.RedirectUri); } if (_configuration == null && Options.ConfigurationManager != null) { _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted); } OpenIdConnectMessage openIdConnectMessage = new OpenIdConnectMessage { ClientId = Options.ClientId, IssuerAddress = _configuration == null ? string.Empty : (_configuration.AuthorizationEndpoint ?? string.Empty), RedirectUri = Options.RedirectUri, RequestType = OpenIdConnectRequestType.AuthenticationRequest, Resource = Options.Resource, ResponseMode = OpenIdConnectResponseModes.FormPost, ResponseType = Options.ResponseType, Scope = Options.Scope, State = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(Options.StateDataFormat.Protect(properties)) }; if (Options.ProtocolValidator.RequireNonce) { openIdConnectMessage.Nonce = Options.ProtocolValidator.GenerateNonce(); if (Options.NonceCache != null) { Options.NonceCache.AddNonce(openIdConnectMessage.Nonce); } else { RememberNonce(openIdConnectMessage.Nonce); } } var notification = new RedirectToIdentityProviderNotification <OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>(Context, Options) { ProtocolMessage = openIdConnectMessage }; await Options.Notifications.RedirectToIdentityProvider(notification); if (!notification.HandledResponse) { string redirectUri = notification.ProtocolMessage.CreateAuthenticationRequestUrl(); if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { _logger.WriteWarning("Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute) returned 'false', redirectUri is: {0}", (redirectUri ?? "null")); } Response.Redirect(redirectUri); } }
private static Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification <OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification) { SetIdTokenHintForLogoutRequest(notification); return(Task.FromResult(0)); }
// This notification can be used to manipulate the OIDC request before it is sent. Here we use it to send the correct policy. private async Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification) { PolicyConfigurationManager mgr = notification.Options.ConfigurationManager as PolicyConfigurationManager; if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { if (notification.Request.Path.Value.ToLower().Contains("signup")) { OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, "B2C_1_TestPolicy"); notification.ProtocolMessage.IssuerAddress = config.EndSessionEndpoint; } else if (notification.Request.Path.Value.ToLower().Contains("signin")) { OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, "B2C_1_signInTestPolicy"); notification.ProtocolMessage.IssuerAddress = config.EndSessionEndpoint; } else if (notification.Request.Path.Value.ToLower().Contains("profile")) { OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, "B2C_1_profileEditingTestPolicy"); notification.ProtocolMessage.IssuerAddress = config.EndSessionEndpoint; } } else { if (notification.Request.Path.Value.ToLower().Contains("signup")) { OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, "B2C_1_TestPolicy"); notification.ProtocolMessage.IssuerAddress = config.AuthorizationEndpoint; } else if (notification.Request.Path.Value.ToLower().Contains("signin")) { OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, "B2C_1_signInTestPolicy"); notification.ProtocolMessage.IssuerAddress = config.AuthorizationEndpoint; } else if (notification.Request.Path.Value.ToLower().Contains("profile")) { OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, "B2C_1_profileEditingTestPolicy"); notification.ProtocolMessage.IssuerAddress = config.AuthorizationEndpoint; } } }
public static Task RedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification) { // If a challenge was issued by the SingleSignOut javascript UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext); if (notification.Request.Uri.AbsolutePath == url.Action("SessionChanged", "Account")) { // Store the state in the cookie so we can distinguish OIDC messages that occurred // as a result of the SingleSignOut javascript. ICookieManager cookieManager = new ChunkingCookieManager(); string cookie = cookieManager.GetRequestCookie(notification.OwinContext, CookieName); AuthenticationTicket ticket = ticketDataFormat.Unprotect(cookie); if (ticket.Properties.Dictionary != null) ticket.Properties.Dictionary[OpenIdConnectAuthenticationDefaults.AuthenticationType + "SingleSignOut"] = notification.ProtocolMessage.State; cookieManager.AppendResponseCookie(notification.OwinContext, CookieName, ticketDataFormat.Protect(ticket), new CookieOptions()); // Return prompt=none request (to tenant specific endpoint) to SessionChanged controller. notification.ProtocolMessage.Prompt = "none"; notification.ProtocolMessage.IssuerAddress = notification.OwinContext.Authentication.User.FindFirst("issEndpoint").Value; string redirectUrl = notification.ProtocolMessage.BuildRedirectUrl(); notification.Response.Redirect(url.Action("SessionChanged", "Account") + "?" + redirectUrl); notification.HandleResponse(); } return Task.FromResult<object>(null); }