/// <summary>
            /// Gets Identity Provider used by a user to initiate Login process.
            /// </summary>
            /// <param name="throwExceptionIfAbsent">Throw exception if current provider settings are missing.</param>
            /// <returns>The Identity Provider.</returns>
            public static IdentityProviderClientConfigurationElement GetCurrentProviderSettings(bool throwExceptionIfAbsent = true)
            {
                HttpCookie currentProviderCookie = HttpContext.Current.Request.Cookies.Get(OpenIdConnectUtilities.CookieCurrentProvider);

                if (currentProviderCookie == null)
                {
                    if (throwExceptionIfAbsent)
                    {
                        RetailLogger.Log.OnlineStoreCookieNotFound(OpenIdConnectUtilities.CookieCurrentProvider, "Required for OpenIdConnect signIn");
                        throw new SecurityException(string.Format("{0} cookie not found.", OpenIdConnectUtilities.CookieCurrentProvider));
                    }
                    else
                    {
                        return(null);
                    }
                }

                IdentityProviderClientConfigurationElement provider = Utilities.GetIdentityProviderFromConfiguration(currentProviderCookie.Value);

                if (provider == null)
                {
                    RetailLogger.Log.OnlineStoreIdentityProviderSpecifiedInRequestCookieNotSupported(currentProviderCookie.Name, currentProviderCookie.Value);
                    throw new SecurityException("Identity Provider specified on request could not be found in the app config. This could happen due to a timeout; login again.");
                }

                return(provider);
            }
Beispiel #2
0
            public ActionResult ProviderSelected()
            {
                string authenticationProviderName = this.Request.Form["SelectedAuthenticationProviderName"];

                IdentityProviderClientConfigurationElement provider = Utilities.GetIdentityProviderFromConfiguration(authenticationProviderName);

                switch (provider.ProviderType)
                {
                case IdentityProviderType.OpenIdConnect:
                    ControllerContext.HttpContext.GetOwinContext().Authentication.Challenge(provider.Name);
                    return(new HttpUnauthorizedResult());

                case IdentityProviderType.ACS:
                    // Storing cookie with current provider (used in Logoff).
                    HttpCookie cookie = new HttpCookie(OpenIdConnectUtilities.CookieCurrentProvider, provider.Name);
                    cookie.Expires  = DateTime.MaxValue;
                    cookie.HttpOnly = true;
                    cookie.Secure   = true;
                    this.HttpContext.Response.Cookies.Add(cookie);

                    string url = string.Format("{0}v2/wsfederation?wa=wsignin1.0&wtrealm={1}", provider.Issuer, provider.RedirectUrl);
                    Response.Redirect(url, true);
                    break;

                default:
                    RetailLogger.Log.OnlineStoreUnsupportedIdentityProviderTypeEncountered(provider.ProviderType.ToString());
                    SecurityException securityException = new SecurityException(string.Format("The identity provider type {0} is not supported", provider.ProviderType));
                    throw securityException;
                }

                return(null);
            }
Beispiel #3
0
            public ActionResult SignOut()
            {
                Uri externalLogOffUri = null;

                if (this.Request.IsAuthenticated)
                {
                    var ctx = Request.GetOwinContext();
                    ctx.Authentication.SignOut(CookieConstants.ApplicationCookieAuthenticationType);

                    IdentityProviderClientConfigurationElement providerClient = OpenIdConnectUtilities.GetCurrentProviderSettings();
                    ////ctx.Authentication.SignOut(providerClient.Name);

                    // Clean up openId nonce cookie. This is just a workaround. Ideally, we should be calling 'ctx.Authentication.SignOut(providerClient.Name)'
                    //// Begin workaround.
                    foreach (string cookieName in ControllerContext.HttpContext.Request.Cookies.AllKeys)
                    {
                        if (cookieName.StartsWith("OpenIdConnect.nonce.", StringComparison.OrdinalIgnoreCase))
                        {
                            OpenIdConnectUtilities.RemoveCookie(cookieName);
                            break;
                        }
                    }

                    //// End workaround.

                    externalLogOffUri = providerClient.LogOffUrl;
                }

                OpenIdConnectUtilities.RemoveCookie(OpenIdConnectUtilities.CookieCurrentProvider);
                ServiceUtilities.CleanUpOnSignOutOrAuthFailure(this.HttpContext);

                return(this.View(SignInController.SignOutViewName, externalLogOffUri));
            }
        /// <summary>
        /// Action invoked on being redirected from open identity provider.
        /// </summary>
        /// <returns>View after being redirected from open identity provider.</returns>
        /// <exception cref="System.NotSupportedException">Thrown when email claim does not exist.</exception>
        public ActionResult OAuthV2Redirect()
        {
            IdentityProviderClientConfigurationElement currentProvider = OpenIdConnectUtilities.GetCurrentProviderSettings();

            // Check whether provider returned an error which could be a case if a user rejected a consent.
            string errorCode = this.HttpContext.Request.Params["error"];

            if (errorCode != null)
            {
                string message = string.Format(
                    CultureInfo.CurrentCulture,
                    "The provider {0} returned error code {1} while processing user's credentials.",
                    currentProvider.Name,
                    errorCode);
                this.Response.Redirect("~", false);
                this.HttpContext.ApplicationInstance.CompleteRequest();
                return(null);
            }

            string authorizationCode = OpenIdConnectUtilities.ValidateRequestAndGetAuthorizationCode();

            if (authorizationCode == null)
            {
                string            message           = "Unable to find the authorization code for the login request.";
                SecurityException securityException = new SecurityException(message);
                throw securityException;
            }

            string bodyParameters = string.Format(
                CultureInfo.InvariantCulture,
                "grant_type=authorization_code&code={0}&redirect_uri={1}&client_id={2}&client_secret={3}",
                authorizationCode,
                currentProvider.RedirectUrl,
                currentProvider.ClientId,
                currentProvider.ClientSecret);

            OpenIdConnectConfiguration providerDiscoveryDocument = OpenIdConnectUtilities.GetDiscoveryDocument(currentProvider.Issuer);

            string returnValuesJson = OpenIdConnectUtilities.HttpPost(new Uri(providerDiscoveryDocument.TokenEndpoint), bodyParameters);

            TokenEndpointResponse tokenResponse = OpenIdConnectUtilities.DeserilizeJson <TokenEndpointResponse>(returnValuesJson);

            JwtSecurityToken token = OpenIdConnectUtilities.GetIdToken(tokenResponse.IdToken);

            Claim emailClaim = token.Claims.SingleOrDefault(c => string.Equals(c.Type, OpenIdConnectUtilities.Email, StringComparison.OrdinalIgnoreCase));

            string email = null;

            // IdentityServer does not return email claim.
            if (emailClaim != null)
            {
                email = emailClaim.Value;
            }

            return(this.GetRedirectionBasedOnAssociatedCustomer(tokenResponse.IdToken, currentProvider.ProviderType, email));
        }
Beispiel #5
0
            /// <summary>
            /// Action invoked on being redirected from open identity provider.
            /// </summary>
            /// <returns>View after being redirected from open identity provider.</returns>
            /// <exception cref="System.NotSupportedException">Thrown when email claim does not exist.</exception>
            public async Task <ActionResult> OAuthV2Redirect()
            {
                IdentityProviderClientConfigurationElement currentProvider = OpenIdConnectUtilities.GetCurrentProviderSettings();

                // Check whether provider returned an error which could be a case if a user rejected a consent.
                string errorCode = ControllerContext.HttpContext.Request.Params["error"];

                if (errorCode != null)
                {
                    string message = string.Format(
                        "The provider {0} returned error code {1} while processing user's credentials.", currentProvider.Name, errorCode);
                    System.Diagnostics.Trace.TraceWarning(message);
                    this.Response.Redirect("~", false);
                    this.HttpContext.ApplicationInstance.CompleteRequest();
                    return(null);
                }

                string authorizationCode = OpenIdConnectUtilities.ValidateRequestAndGetAuthorizationCode(this.HttpContext);

                if (authorizationCode == null)
                {
                    SecurityException securityException = new SecurityException("Unable to find the authorization code for the login request.");
                    RetailLogger.Log.OnlineStoreAuthorizationCodeNotFoundForLogOnRequest(securityException);
                    throw securityException;
                }

                string bodyParameters = string.Format(
                    "grant_type=authorization_code&code={0}&redirect_uri={1}&client_id={2}&client_secret={3}",
                    authorizationCode,
                    currentProvider.RedirectUrl,
                    currentProvider.ClientId,
                    currentProvider.ClientSecret);

                OpenIdConnectConfiguration providerDiscoveryDocument = OpenIdConnectUtilities.GetDiscoveryDocument(currentProvider.Issuer);

                string returnValuesJson = OpenIdConnectUtilities.HttpPost(new Uri(providerDiscoveryDocument.TokenEndpoint), bodyParameters);

                TokenEndpointResponse tokenResponse = OpenIdConnectUtilities.DeserilizeJson <TokenEndpointResponse>(returnValuesJson);

                JwtSecurityToken token = OpenIdConnectUtilities.GetIdToken(tokenResponse.IdToken);

                Claim emailClaim = token.Claims.SingleOrDefault(c => string.Equals(c.Type, CookieConstants.Email, StringComparison.OrdinalIgnoreCase));

                if (emailClaim == null)
                {
                    RetailLogger.Log.OnlineStoreClaimNotFound(CookieConstants.Email, "Required for sign up using OpenIdAuth");
                    throw new SecurityException("Email claim does not exist.");
                }

                RedirectToRouteResult redirectResult = await this.GetRedirectionBasedOnAssociatedCustomer(this.HttpContext, tokenResponse.IdToken, currentProvider.ProviderType, emailClaim.Value);

                return(redirectResult);
            }
        public ActionResult FederatedSignOut()
        {
            IdentityProviderClientConfigurationElement providerClient = OpenIdConnectUtilities.GetCurrentProviderSettings();
            Uri externalLogOffUri = providerClient.LogOffUrl;

            OpenIdConnectUtilities.RemoveCookie(OpenIdConnectUtilities.CookieCurrentProvider);
            OpenIdConnectUtilities.RemoveCookie(OpenIdConnectUtilities.CookieCurrentProviderType);
            OpenIdConnectUtilities.CleanUpOnSignOutOrAuthFailure(this.HttpContext);

            var model = new FederatedSignOutApiModel()
            {
                LogOffUri = externalLogOffUri
            };

            return(this.View(model));
        }
Beispiel #7
0
            private static string GetAuthenticationProviderName(string authenticationProviderUrl)
            {
                IDictionary <string, IdentityProviderClientConfigurationElement> identityProviderDictionary = GetIdentityProvidersFromConfig();

                IdentityProviderClientConfigurationElement providerConfig = identityProviderDictionary.Values.Where(v => string.Equals(v.Issuer.OriginalString, authenticationProviderUrl, StringComparison.OrdinalIgnoreCase)).SingleOrDefault();

                if (providerConfig != null)
                {
                    return(providerConfig.Name);
                }
                else
                {
                    RetailLogger.Log.OnlineStoreUnsupportedIdentityProviderTypeEncountered(authenticationProviderUrl);
                    return(authenticationProviderUrl);
                }
            }
Beispiel #8
0
            private static IEnumerable <AuthenticationDescription> GetAuthenticationProviders(HttpContextBase httpContextBase)
            {
                if (SignInController.authenticationProviders == null)
                {
                    IDictionary <string, IdentityProviderClientConfigurationElement> identityProviderDictionary = GetIdentityProvidersFromConfig();
                    List <AuthenticationDescription> authDescriptions = new List <AuthenticationDescription>();

                    foreach (AuthenticationDescription openIdConnectDescription in httpContextBase.GetOwinContext().Authentication.GetAuthenticationTypes().Where(t => t.Properties.ContainsKey(CookieConstants.Caption)))
                    {
                        KeyValuePair <string, object> authenticationType = openIdConnectDescription.Properties.Single(p => p.Key == CookieConstants.AuthenticationType);
                        KeyValuePair <string, object> caption            = openIdConnectDescription.Properties.Single(p => p.Key == CookieConstants.Caption);
                        AuthenticationDescription     authDescription    = new AuthenticationDescription()
                        {
                            AuthenticationType = authenticationType.Value.ToString(),
                            Caption            = caption.Value.ToString()
                        };

                        IdentityProviderClientConfigurationElement identityProvider = identityProviderDictionary[authDescription.AuthenticationType];
                        authDescription.Properties.Add(SignInController.ImageUrl, identityProvider.ImageUrl);
                        authDescription.Properties.Add(SignInController.DisplayIndex, identityProvider.DisplayIndex);

                        authDescriptions.Add(authDescription);
                    }

                    foreach (IdentityProviderClientConfigurationElement identityProvider in identityProviderDictionary.Values)
                    {
                        if (identityProvider.ProviderType == IdentityProviderType.ACS)
                        {
                            AuthenticationDescription authDescription = new AuthenticationDescription()
                            {
                                AuthenticationType = identityProvider.Name,
                                Caption            = identityProvider.Name
                            };

                            authDescription.Properties.Add(SignInController.ImageUrl, identityProvider.ImageUrl);
                            authDescription.Properties.Add(SignInController.DisplayIndex, identityProvider.DisplayIndex);
                            authDescriptions.Add(authDescription);
                        }
                    }

                    SignInController.authenticationProviders = authDescriptions.OrderBy(ad => ad.Properties[DisplayIndex]);
                }

                return(SignInController.authenticationProviders);
            }
        public ActionResult LoginPost(string provider)
        {
            IdentityProviderClientConfigurationElement providerConfig = OpenIdConnectUtilities.GetIdentityProviderFromConfiguration(provider);

            switch (providerConfig.ProviderType)
            {
            case IdentityProviderType.OpenIdConnect:
                this.ControllerContext.HttpContext.GetOwinContext().Authentication.Challenge(providerConfig.Name);
                return(new HttpUnauthorizedResult());

            case IdentityProviderType.ACS:

                // Storing cookie with current provider (used in Logoff).
                OpenIdConnectUtilities.SetCookie(
                    this.HttpContext,
                    OpenIdConnectUtilities.CookieCurrentProvider,
                    providerConfig.Name);
                OpenIdConnectUtilities.SetCookie(
                    this.HttpContext,
                    OpenIdConnectUtilities.CookieCurrentProviderType,
                    providerConfig.ProviderType.ToString());

                string url = string.Format(
                    CultureInfo.InvariantCulture,
                    "{0}v2/wsfederation?wa=wsignin1.0&wtrealm={1}",
                    providerConfig.Issuer,
                    providerConfig.RedirectUrl);
                this.Response.Redirect(url, true);
                break;

            default:
                SecurityException securityException =
                    new SecurityException(
                        string.Format(
                            CultureInfo.InvariantCulture,
                            "The identity provider type {0} is not supported",
                            providerConfig.ProviderType));
                throw securityException;
            }

            return(null);
        }
Beispiel #10
0
            private static OpenIdConnectAuthenticationOptions GetOpenIdConnectAuthenticationOptions(IdentityProviderClientConfigurationElement provider)
            {
                OpenIdConnectAuthenticationOptions options = new OpenIdConnectAuthenticationOptions
                {
                    AuthenticationType = provider.Name,
                    Caption            = provider.Name,
                    ClientId           = provider.ClientId,
                    Authority          = provider.Issuer.ToString(),
                    RedirectUri        = provider.RedirectUrl.ToString(),

                    // Leveraging Authorization Code grant
                    ResponseType  = "code",
                    Scope         = "openid email",
                    Notifications = GetOpenIdConnectAuthenticationNotifications()
                };

                return(options);
            }