Пример #1
0
        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();
        }
Пример #2
0
 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);
        }
Пример #6
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;
     }
 }
Пример #7
0
        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;
        }
Пример #10
0
        /*
         *  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;
        }
Пример #12
0
        /// <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);
            }
        }
Пример #17
0
        /// <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);
            }
        }
Пример #19
0
 private static Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification <OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
 {
     SetIdTokenHintForLogoutRequest(notification);
     return(Task.FromResult(0));
 }
Пример #20
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;
             }
         }
 }
Пример #21
0
        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);
        }