protected override async Task <bool> HandleUnauthorizedAsync(ChallengeContext context) { var notification = new MatchEndpointContext(Context, Options); if (Options.UserinfoEndpointPath.HasValue && Options.UserinfoEndpointPath == Request.Path) { notification.MatchesUserinfoEndpoint(); } await Options.Provider.MatchEndpoint(notification); // Return true to indicate to the authentication pipeline that // the 401 response shouldn't be handled by the other middleware. if (!notification.IsUserinfoEndpoint) { return(true); } Response.StatusCode = 401; Response.Headers[HeaderNames.WWWAuthenticate] = "error=" + OpenIdConnectConstants.Errors.InvalidGrant; return(false); }
public override async Task <bool> HandleRequestAsync() { 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 && !Request.IsHttps) { // Return the native error page for endpoints involving the user participation. if (notification.IsAuthorizationEndpoint || notification.IsLogoutEndpoint) { 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) { 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); }
protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { 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(AuthenticateResult.Skip()); } // Try to retrieve the current OpenID Connect request from the ASP.NET context. // If the request cannot be found, this means that this middleware was configured // to use the automatic authentication mode and that HandleAuthenticateAsync // 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.ToDictionary()); } else if (string.Equals(Request.Method, "POST", StringComparison.OrdinalIgnoreCase)) { if (string.IsNullOrEmpty(Request.ContentType)) { return(AuthenticateResult.Skip()); } else if (!Request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase)) { return(AuthenticateResult.Skip()); } var form = await Request.ReadFormAsync(Context.RequestAborted); request = new OpenIdConnectMessage(form.ToDictionary()); } } // Missing or invalid requests are ignored in HandleAuthenticateAsync: // in this case, Skip is used to indicate authentication failed. if (request == null) { return(AuthenticateResult.Skip()); } if (notification.IsAuthorizationEndpoint || notification.IsLogoutEndpoint) { if (string.IsNullOrEmpty(request.IdTokenHint)) { return(AuthenticateResult.Skip()); } var ticket = await DeserializeIdentityTokenAsync(request.IdTokenHint, request); if (ticket == null) { Logger.LogWarning("The identity token extracted from the id_token_hint " + "parameter was invalid and has been ignored."); return(AuthenticateResult.Skip()); } // Tickets are returned even if they // are considered invalid (e.g expired). return(AuthenticateResult.Success(ticket)); } else if (notification.IsUserinfoEndpoint) { string token; if (!string.IsNullOrEmpty(request.AccessToken)) { token = request.AccessToken; } else { string header = Request.Headers[HeaderNames.Authorization]; if (string.IsNullOrEmpty(header)) { return(AuthenticateResult.Skip()); } if (!header.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) { return(AuthenticateResult.Skip()); } token = header.Substring("Bearer ".Length); if (string.IsNullOrWhiteSpace(token)) { return(AuthenticateResult.Skip()); } } var ticket = await DeserializeAccessTokenAsync(token, request); if (ticket == null) { Logger.LogWarning("The access token extracted from the userinfo " + "request was expired and has been ignored."); return(AuthenticateResult.Skip()); } if (!ticket.Properties.ExpiresUtc.HasValue || ticket.Properties.ExpiresUtc < Options.SystemClock.UtcNow) { Logger.LogWarning("The access token extracted from the userinfo " + "request was expired and has been ignored."); return(AuthenticateResult.Skip()); } return(AuthenticateResult.Success(ticket)); } return(AuthenticateResult.Skip()); }