Exemplo n.º 1
0
        protected override async Task ApplyResponseChallengeAsync()
        {
            var context = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode);

            if (context == null || Response.StatusCode != 401)
            {
                return;
            }

            var notification = new MatchEndpointContext(Context, Options);

            if (Options.UserinfoEndpointPath.HasValue &&
                Options.UserinfoEndpointPath == Request.Path)
            {
                notification.MatchesUserinfoEndpoint();
            }

            await Options.Provider.MatchEndpoint(notification);

            if (!notification.IsUserinfoEndpoint)
            {
                return;
            }

            Response.StatusCode = 401;
            Response.Headers.Set("WWW-Authenticate", "error=" + OpenIdConnectConstants.Errors.InvalidGrant);
        }
Exemplo n.º 2
0
        public override async Task <bool> InvokeAsync()
        {
            var notification = new MatchEndpointContext(Context, Options);

            if (Options.AuthorizationEndpointPath.HasValue &&
                Options.AuthorizationEndpointPath == Request.Path)
            {
                notification.MatchesAuthorizationEndpoint();
            }

            else if (Options.ConfigurationEndpointPath.HasValue &&
                     Options.ConfigurationEndpointPath == Request.Path)
            {
                notification.MatchesConfigurationEndpoint();
            }

            else if (Options.CryptographyEndpointPath.HasValue &&
                     Options.CryptographyEndpointPath == Request.Path)
            {
                notification.MatchesCryptographyEndpoint();
            }

            else if (Options.IntrospectionEndpointPath.HasValue &&
                     Options.IntrospectionEndpointPath == Request.Path)
            {
                notification.MatchesIntrospectionEndpoint();
            }

            else if (Options.LogoutEndpointPath.HasValue &&
                     Options.LogoutEndpointPath == Request.Path)
            {
                notification.MatchesLogoutEndpoint();
            }

            else if (Options.RevocationEndpointPath.HasValue &&
                     Options.RevocationEndpointPath == Request.Path)
            {
                notification.MatchesRevocationEndpoint();
            }

            else if (Options.TokenEndpointPath.HasValue &&
                     Options.TokenEndpointPath == Request.Path)
            {
                notification.MatchesTokenEndpoint();
            }

            else if (Options.UserinfoEndpointPath.HasValue &&
                     Options.UserinfoEndpointPath == Request.Path)
            {
                notification.MatchesUserinfoEndpoint();
            }

            await Options.Provider.MatchEndpoint(notification);

            if (notification.HandledResponse)
            {
                return(true);
            }

            else if (notification.Skipped)
            {
                return(false);
            }

            // Reject non-HTTPS requests handled by ASOS if AllowInsecureHttp is not set to true.
            if (!Options.AllowInsecureHttp && string.Equals(Request.Scheme, Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase))
            {
                // Return the native error page for endpoints involving the user participation.
                if (notification.IsAuthorizationEndpoint || notification.IsLogoutEndpoint)
                {
                    Options.Logger.LogWarning("The current request was rejected because the OpenID Connect server middleware " +
                                              "has been configured to reject HTTP requests. To permanently disable the transport " +
                                              "security requirement, set 'OpenIdConnectServerOptions.AllowInsecureHttp' to 'true'.");

                    return(await SendNativePageAsync(new OpenIdConnectResponse {
                        Error = OpenIdConnectConstants.Errors.InvalidRequest,
                        ErrorDescription = "This server only accepts HTTPS requests."
                    }));
                }

                // Return a JSON error for endpoints that don't involve the user participation.
                else if (notification.IsConfigurationEndpoint || notification.IsCryptographyEndpoint ||
                         notification.IsIntrospectionEndpoint || notification.IsRevocationEndpoint ||
                         notification.IsTokenEndpoint || notification.IsUserinfoEndpoint)
                {
                    Options.Logger.LogWarning("The current request was rejected because the OpenID Connect server middleware " +
                                              "has been configured to reject HTTP requests. To permanently disable the transport " +
                                              "security requirement, set 'OpenIdConnectServerOptions.AllowInsecureHttp' to 'true'.");

                    return(await SendPayloadAsync(new OpenIdConnectResponse {
                        Error = OpenIdConnectConstants.Errors.InvalidRequest,
                        ErrorDescription = "This server only accepts HTTPS requests."
                    }));
                }
            }

            if (notification.IsAuthorizationEndpoint)
            {
                return(await InvokeAuthorizationEndpointAsync());
            }

            else if (notification.IsConfigurationEndpoint)
            {
                return(await InvokeConfigurationEndpointAsync());
            }

            else if (notification.IsCryptographyEndpoint)
            {
                return(await InvokeCryptographyEndpointAsync());
            }

            else if (notification.IsIntrospectionEndpoint)
            {
                return(await InvokeIntrospectionEndpointAsync());
            }

            else if (notification.IsLogoutEndpoint)
            {
                return(await InvokeLogoutEndpointAsync());
            }

            else if (notification.IsRevocationEndpoint)
            {
                return(await InvokeRevocationEndpointAsync());
            }

            else if (notification.IsTokenEndpoint)
            {
                return(await InvokeTokenEndpointAsync());
            }

            else if (notification.IsUserinfoEndpoint)
            {
                return(await InvokeUserinfoEndpointAsync());
            }

            return(false);
        }
Exemplo n.º 3
0
        // Implementing AuthenticateCoreAsync allows the inner application
        // to retrieve the identity extracted from the optional id_token_hint.
        protected override async Task <AuthenticationTicket> AuthenticateCoreAsync()
        {
            var notification = new MatchEndpointContext(Context, Options);

            if (Options.AuthorizationEndpointPath.HasValue &&
                Options.AuthorizationEndpointPath == Request.Path)
            {
                notification.MatchesAuthorizationEndpoint();
            }

            else if (Options.LogoutEndpointPath.HasValue &&
                     Options.LogoutEndpointPath == Request.Path)
            {
                notification.MatchesLogoutEndpoint();
            }

            else if (Options.UserinfoEndpointPath.HasValue &&
                     Options.UserinfoEndpointPath == Request.Path)
            {
                notification.MatchesUserinfoEndpoint();
            }

            await Options.Provider.MatchEndpoint(notification);

            if (!notification.IsAuthorizationEndpoint &&
                !notification.IsLogoutEndpoint &&
                !notification.IsUserinfoEndpoint)
            {
                return(null);
            }

            // Try to retrieve the current OpenID Connect request from the OWIN context.
            // If the request cannot be found, this means that this middleware was configured
            // to use the automatic authentication mode and that AuthenticateCoreAsync
            // was invoked before Invoke*EndpointAsync: in this case, the OpenID Connect
            // request is directly extracted from the query string or the request form.
            var request = Context.GetOpenIdConnectRequest();

            if (request == null)
            {
                if (string.Equals(Request.Method, "GET", StringComparison.OrdinalIgnoreCase))
                {
                    request = new OpenIdConnectMessage(Request.Query);
                }

                else if (string.Equals(Request.Method, "POST", StringComparison.OrdinalIgnoreCase))
                {
                    if (string.IsNullOrEmpty(Request.ContentType))
                    {
                        return(null);
                    }

                    else if (!Request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase))
                    {
                        return(null);
                    }

                    request = new OpenIdConnectMessage(await Request.ReadFormAsync());
                }
            }

            // Missing or invalid requests are ignored in AuthenticateCoreAsync:
            // in this case, null is always returned to indicate authentication failed.
            if (request == null)
            {
                return(null);
            }

            if (notification.IsAuthorizationEndpoint || notification.IsLogoutEndpoint)
            {
                if (string.IsNullOrEmpty(request.IdTokenHint))
                {
                    return(null);
                }

                var ticket = await DeserializeIdentityTokenAsync(request.IdTokenHint, request);

                if (ticket == null)
                {
                    Options.Logger.LogWarning("The identity token extracted from the id_token_hint " +
                                              "parameter was invalid and has been ignored.");

                    return(null);
                }

                // Tickets are returned even if they
                // are considered invalid (e.g expired).
                return(ticket);
            }

            else if (notification.IsUserinfoEndpoint)
            {
                string token;
                if (!string.IsNullOrEmpty(request.AccessToken))
                {
                    token = request.AccessToken;
                }

                else
                {
                    var header = Request.Headers.Get("Authorization");
                    if (string.IsNullOrEmpty(header))
                    {
                        return(null);
                    }

                    if (!header.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
                    {
                        return(null);
                    }

                    token = header.Substring("Bearer ".Length);
                    if (string.IsNullOrWhiteSpace(token))
                    {
                        return(null);
                    }
                }

                var ticket = await DeserializeAccessTokenAsync(token, request);

                if (ticket == null)
                {
                    Options.Logger.LogWarning("The access token extracted from the userinfo " +
                                              "request was invalid and has been ignored.");

                    return(null);
                }

                if (!ticket.Properties.ExpiresUtc.HasValue ||
                    ticket.Properties.ExpiresUtc < Options.SystemClock.UtcNow)
                {
                    Options.Logger.LogWarning("The access token extracted from the userinfo " +
                                              "request was expired and has been ignored.");

                    return(null);
                }

                return(ticket);
            }

            return(null);
        }