private static async Task<OpenIdConnectConfiguration> GetOpenIdConnectConfigurationAsync(RedirectContext context, string defaultPolicy) { var manager = (PolicyConfigurationManager)context.Options.ConfigurationManager; var policy = context.Properties.Items.ContainsKey(AuthenticationConstants.B2CPolicy) ? context.Properties.Items[AuthenticationConstants.B2CPolicy] : defaultPolicy; var configuration = await manager.GetConfigurationByPolicyAsync(CancellationToken.None, policy); return configuration; }
private async Task OnRedirectToIdentityProviderForSignOut(RedirectContext context) { AzureAdSettings azureADSettings = GetAdSettings(context); var configuration = await GetOpenIdConnectConfigurationAsync(context, azureADSettings.B2CPolicySettings.SignInOrSignUpPolicy); context.ProtocolMessage.IssuerAddress = configuration.EndSessionEndpoint; }
/// <summary> /// Called prior to the OIDC middleware redirecting to the authentication endpoint. In the event we are signing up a tenant, we need to /// put the "admin_consent" value for the prompt query string parameter. AAD uses this to show the admin consent flow. /// </summary> /// <param name="context">The <see cref="Microsoft.AspNetCore.Authentication.OpenIdConnect.RedirectContext"/> for this event.</param> /// <returns>A completed <see cref="System.Threading.Tasks.Task"/></returns> public override Task RedirectToIdentityProvider(RedirectContext context) { if (context.IsSigningUp()) { context.ProtocolMessage.Prompt = "admin_consent"; } _logger.RedirectToIdentityProvider(); return Task.FromResult(0); }
internal static Task RedirectToIdentityProvider(RedirectContext context) { eventsFired.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"); } return Task.FromResult(0); }
private static Task Redirect(IConfiguration configuration, Microsoft.AspNetCore.Authentication.OpenIdConnect.RedirectContext ctx) { //ctx.ProtocolMessage.RedirectUri = String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}", configuration.GetValue<String>(ConfigurationSectionKeys.RedirectHost), configuration.GetValue<String>("AzureAd:CallbackPath")); return(Task.CompletedTask); }
/// <summary> /// Invoked before redirecting to the identity provider to sign out. /// </summary> public virtual Task RedirectToIdentityProviderForSignOut(RedirectContext context) => OnRedirectToIdentityProviderForSignOut(context);
/// <summary> /// Invoked before redirecting to the identity provider to authenticate. This can be used to set ProtocolMessage.State /// that will be persisted through the authentication process. The ProtocolMessage can also be used to add or customize /// parameters sent to the identity provider. /// </summary> public virtual Task RedirectToIdentityProvider(RedirectContext context) => OnRedirectToIdentityProvider(context);
/// <summary> /// Handles Signout /// </summary> /// <returns></returns> protected override async Task HandleSignOutAsync(SignOutContext signout) { if (signout != null) { if (_configuration == null && Options.ConfigurationManager != null) { _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted); } var message = new OpenIdConnectMessage() { IssuerAddress = _configuration == null ? string.Empty : (_configuration.EndSessionEndpoint ?? string.Empty), }; // Set End_Session_Endpoint in order: // 1. properties.Redirect // 2. Options.PostLogoutRedirectUri var properties = new AuthenticationProperties(signout.Properties); var logoutRedirectUri = properties.RedirectUri; if (!string.IsNullOrEmpty(logoutRedirectUri)) { // Relative to PathBase if (logoutRedirectUri.StartsWith("/", StringComparison.Ordinal)) { logoutRedirectUri = BuildRedirectUri(logoutRedirectUri); } message.PostLogoutRedirectUri = logoutRedirectUri; } else if (!string.IsNullOrEmpty(Options.PostLogoutRedirectUri)) { logoutRedirectUri = Options.PostLogoutRedirectUri; // Relative to PathBase if (logoutRedirectUri.StartsWith("/", StringComparison.Ordinal)) { logoutRedirectUri = BuildRedirectUri(logoutRedirectUri); } message.PostLogoutRedirectUri = logoutRedirectUri; } message.IdTokenHint = await Context.Authentication.GetTokenAsync(OpenIdConnectParameterNames.IdToken); var redirectContext = new RedirectContext(Context, Options, properties) { ProtocolMessage = message }; await Options.Events.RedirectToIdentityProviderForSignOut(redirectContext); if (redirectContext.HandledResponse) { Logger.RedirectToIdentityProviderForSignOutHandledResponse(); return; } else if (redirectContext.Skipped) { Logger.RedirectToIdentityProviderForSignOutSkipped(); return; } message = redirectContext.ProtocolMessage; if (Options.AuthenticationMethod == OpenIdConnectRedirectBehavior.RedirectGet) { var redirectUri = message.CreateLogoutRequestUrl(); if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { Logger.InvalidLogoutQueryStringRedirectUrl(redirectUri); } Response.Redirect(redirectUri); } else if (Options.AuthenticationMethod == OpenIdConnectRedirectBehavior.FormPost) { var inputs = new StringBuilder(); foreach (var parameter in message.Parameters) { var name = HtmlEncoder.Encode(parameter.Key); var value = HtmlEncoder.Encode(parameter.Value); var input = string.Format(CultureInfo.InvariantCulture, InputTagFormat, name, value); inputs.AppendLine(input); } var issuer = HtmlEncoder.Encode(message.IssuerAddress); var content = string.Format(CultureInfo.InvariantCulture, HtmlFormFormat, issuer, inputs); var buffer = Encoding.UTF8.GetBytes(content); Response.ContentLength = buffer.Length; Response.ContentType = "text/html;charset=UTF-8"; // Emit Cache-Control=no-cache to prevent client caching. Response.Headers[HeaderNames.CacheControl] = "no-cache"; Response.Headers[HeaderNames.Pragma] = "no-cache"; Response.Headers[HeaderNames.Expires] = "-1"; await Response.Body.WriteAsync(buffer, 0, buffer.Length); } } }
/// <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 <bool> HandleUnauthorizedAsync(ChallengeContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } Logger.EnteringOpenIdAuthenticationHandlerHandleUnauthorizedAsync(GetType().FullName); // order for local RedirectUri // 1. challenge.Properties.RedirectUri // 2. CurrentUri if RedirectUri is not set) var properties = new AuthenticationProperties(context.Properties) { ExpiresUtc = Options.SystemClock.UtcNow.Add(Options.RemoteAuthenticationTimeout) }; if (string.IsNullOrEmpty(properties.RedirectUri)) { properties.RedirectUri = CurrentUri; } Logger.PostAuthenticationLocalRedirect(properties.RedirectUri); 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 = BuildRedirectUri(Options.CallbackPath), Resource = Options.Resource, ResponseType = Options.ResponseType, Scope = string.Join(" ", 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(); WriteNonceCookie(message.Nonce); } GenerateCorrelationId(properties); var redirectContext = new RedirectContext(Context, Options, properties) { ProtocolMessage = message }; await Options.Events.RedirectToIdentityProvider(redirectContext); if (redirectContext.HandledResponse) { Logger.RedirectToIdentityProviderHandledResponse(); return(true); } else if (redirectContext.Skipped) { Logger.RedirectToIdentityProviderSkipped(); return(false); } message = redirectContext.ProtocolMessage; if (!string.IsNullOrEmpty(message.State)) { properties.Items[OpenIdConnectDefaults.UserstatePropertiesKey] = message.State; } // When redeeming a 'code' for an AccessToken, this value is needed properties.Items.Add(OpenIdConnectDefaults.RedirectUriForCodePropertiesKey, message.RedirectUri); message.State = Options.StateDataFormat.Protect(properties); if (Options.AuthenticationMethod == OpenIdConnectRedirectBehavior.RedirectGet) { var redirectUri = message.CreateAuthenticationRequestUrl(); if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute)) { Logger.InvalidAuthenticationRequestUrl(redirectUri); } Response.Redirect(redirectUri); return(true); } else if (Options.AuthenticationMethod == OpenIdConnectRedirectBehavior.FormPost) { var inputs = new StringBuilder(); foreach (var parameter in message.Parameters) { var name = HtmlEncoder.Encode(parameter.Key); var value = HtmlEncoder.Encode(parameter.Value); var input = string.Format(CultureInfo.InvariantCulture, InputTagFormat, name, value); inputs.AppendLine(input); } var issuer = HtmlEncoder.Encode(message.IssuerAddress); var content = string.Format(CultureInfo.InvariantCulture, HtmlFormFormat, issuer, inputs); var buffer = Encoding.UTF8.GetBytes(content); Response.ContentLength = buffer.Length; Response.ContentType = "text/html;charset=UTF-8"; // Emit Cache-Control=no-cache to prevent client caching. Response.Headers[HeaderNames.CacheControl] = "no-cache"; Response.Headers[HeaderNames.Pragma] = "no-cache"; Response.Headers[HeaderNames.Expires] = "-1"; await Response.Body.WriteAsync(buffer, 0, buffer.Length); return(true); } throw new NotImplementedException($"An unsupported authentication method has been configured: {Options.AuthenticationMethod}"); }
public virtual Task RedirectToIdentityProviderForSignOut(RedirectContext context) => OnRedirectToIdentityProviderForSignOut(context);
public virtual Task RedirectToIdentityProvider(RedirectContext context) => OnRedirectToIdentityProvider(context);