private async Task <bool> SendConfigurationResponseAsync(OpenIdConnectResponse response) { var request = Context.GetOpenIdConnectRequest(); Context.SetOpenIdConnectResponse(response); response.SetProperty(OpenIdConnectConstants.Properties.MessageType, OpenIdConnectConstants.MessageTypes.ConfigurationResponse); var notification = new ApplyConfigurationResponseContext(Context, Options, request, response); await Options.Provider.ApplyConfigurationResponse(notification); if (notification.HandledResponse) { Logger.LogDebug("The configuration request was handled in user code."); return(true); } else if (notification.Skipped) { Logger.LogDebug("The default configuration request handling was skipped from user code."); return(false); } Logger.LogInformation("The configuration response was successfully returned: {Response}.", response); return(await SendPayloadAsync(response)); }
private async Task <bool> SendConfigurationResponseAsync(OpenIdConnectResponse response) { var request = Context.GetOpenIdConnectRequest(); if (request == null) { request = new OpenIdConnectRequest(); } Context.SetOpenIdConnectResponse(response); var notification = new ApplyConfigurationResponseContext(Context, Options, request, response); await Options.Provider.ApplyConfigurationResponse(notification); if (notification.HandledResponse) { return(true); } else if (notification.Skipped) { return(false); } return(await SendPayloadAsync(response)); }
/// <summary> /// Represents an event called before the configuration response is returned to the caller. /// </summary> /// <param name="context">The context instance associated with this event.</param> /// <returns>A <see cref="Task"/> that can be used to monitor the asynchronous operation.</returns> public virtual Task ApplyConfigurationResponse(ApplyConfigurationResponseContext context) => OnApplyConfigurationResponse(context);
private async Task <bool> InvokeConfigurationEndpointAsync() { // Metadata requests must be made via GET. // See http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest if (!string.Equals(Request.Method, "GET", StringComparison.OrdinalIgnoreCase)) { Options.Logger.LogError("The discovery request was rejected because an invalid " + "HTTP method was used: {Method}.", Request.Method); return(await SendErrorPayloadAsync(new OpenIdConnectMessage { Error = OpenIdConnectConstants.Errors.InvalidRequest, ErrorDescription = "Invalid HTTP method: make sure to use GET." })); } var validatingContext = new ValidateConfigurationRequestContext(Context, Options); await Options.Provider.ValidateConfigurationRequest(validatingContext); // Stop processing the request if Validated was not called. if (!validatingContext.IsValidated) { Options.Logger.LogError("The configuration request was rejected."); return(await SendErrorPayloadAsync(new OpenIdConnectMessage { Error = validatingContext.Error ?? OpenIdConnectConstants.Errors.InvalidRequest, ErrorDescription = validatingContext.ErrorDescription, ErrorUri = validatingContext.ErrorUri })); } var notification = new HandleConfigurationRequestContext(Context, Options); notification.Issuer = Context.GetIssuer(Options); if (Options.AuthorizationEndpointPath.HasValue) { notification.AuthorizationEndpoint = notification.Issuer.AddPath(Options.AuthorizationEndpointPath); } if (Options.CryptographyEndpointPath.HasValue) { notification.CryptographyEndpoint = notification.Issuer.AddPath(Options.CryptographyEndpointPath); } if (Options.UserinfoEndpointPath.HasValue) { notification.UserinfoEndpoint = notification.Issuer.AddPath(Options.UserinfoEndpointPath); } if (Options.IntrospectionEndpointPath.HasValue) { notification.IntrospectionEndpoint = notification.Issuer.AddPath(Options.IntrospectionEndpointPath); } if (Options.TokenEndpointPath.HasValue) { notification.TokenEndpoint = notification.Issuer.AddPath(Options.TokenEndpointPath); } if (Options.LogoutEndpointPath.HasValue) { notification.LogoutEndpoint = notification.Issuer.AddPath(Options.LogoutEndpointPath); } if (Options.AuthorizationEndpointPath.HasValue) { // Only expose the implicit grant type if the token // endpoint has not been explicitly disabled. notification.GrantTypes.Add(OpenIdConnectConstants.GrantTypes.Implicit); if (Options.TokenEndpointPath.HasValue) { // Only expose the authorization code and refresh token grant types // if both the authorization and the token endpoints are enabled. notification.GrantTypes.Add(OpenIdConnectConstants.GrantTypes.AuthorizationCode); } } if (Options.TokenEndpointPath.HasValue) { notification.GrantTypes.Add(OpenIdConnectConstants.GrantTypes.RefreshToken); // If the authorization endpoint is disabled, assume the authorization server will // allow the client credentials and resource owner password credentials grant types. if (!Options.AuthorizationEndpointPath.HasValue) { notification.GrantTypes.Add(OpenIdConnectConstants.GrantTypes.ClientCredentials); notification.GrantTypes.Add(OpenIdConnectConstants.GrantTypes.Password); } } // Only populate response_modes_supported and response_types_supported // if the authorization endpoint is available. if (Options.AuthorizationEndpointPath.HasValue) { notification.ResponseModes.Add(OpenIdConnectConstants.ResponseModes.FormPost); notification.ResponseModes.Add(OpenIdConnectConstants.ResponseModes.Fragment); notification.ResponseModes.Add(OpenIdConnectConstants.ResponseModes.Query); notification.ResponseTypes.Add(OpenIdConnectConstants.ResponseTypes.Token); notification.ResponseTypes.Add(OpenIdConnectConstants.ResponseTypes.IdToken); notification.ResponseTypes.Add( OpenIdConnectConstants.ResponseTypes.IdToken + ' ' + OpenIdConnectConstants.ResponseTypes.Token); // Only expose response types containing code when // the token endpoint has not been explicitly disabled. if (Options.TokenEndpointPath.HasValue) { notification.ResponseTypes.Add(OpenIdConnectConstants.ResponseTypes.Code); notification.ResponseTypes.Add( OpenIdConnectConstants.ResponseTypes.Code + ' ' + OpenIdConnectConstants.ResponseTypes.Token); notification.ResponseTypes.Add( OpenIdConnectConstants.ResponseTypes.Code + ' ' + OpenIdConnectConstants.ResponseTypes.IdToken); notification.ResponseTypes.Add( OpenIdConnectConstants.ResponseTypes.Code + ' ' + OpenIdConnectConstants.ResponseTypes.IdToken + ' ' + OpenIdConnectConstants.ResponseTypes.Token); } } notification.Scopes.Add(OpenIdConnectConstants.Scopes.OpenId); notification.SubjectTypes.Add(OpenIdConnectConstants.SubjectTypes.Public); notification.SigningAlgorithms.Add(OpenIdConnectConstants.Algorithms.RS256); await Options.Provider.HandleConfigurationRequest(notification); if (notification.HandledResponse) { return(true); } else if (notification.Skipped) { return(false); } var payload = new JObject(); payload.Add(OpenIdConnectConstants.Metadata.Issuer, notification.Issuer); if (!string.IsNullOrEmpty(notification.AuthorizationEndpoint)) { payload.Add(OpenIdConnectConstants.Metadata.AuthorizationEndpoint, notification.AuthorizationEndpoint); } if (!string.IsNullOrEmpty(notification.UserinfoEndpoint)) { payload.Add(OpenIdConnectConstants.Metadata.UserinfoEndpoint, notification.UserinfoEndpoint); } if (!string.IsNullOrEmpty(notification.IntrospectionEndpoint)) { payload.Add(OpenIdConnectConstants.Metadata.IntrospectionEndpoint, notification.IntrospectionEndpoint); } if (!string.IsNullOrEmpty(notification.TokenEndpoint)) { payload.Add(OpenIdConnectConstants.Metadata.TokenEndpoint, notification.TokenEndpoint); } if (!string.IsNullOrEmpty(notification.LogoutEndpoint)) { payload.Add(OpenIdConnectConstants.Metadata.EndSessionEndpoint, notification.LogoutEndpoint); } if (!string.IsNullOrEmpty(notification.CryptographyEndpoint)) { payload.Add(OpenIdConnectConstants.Metadata.JwksUri, notification.CryptographyEndpoint); } payload.Add(OpenIdConnectConstants.Metadata.GrantTypesSupported, JArray.FromObject(notification.GrantTypes.Distinct())); payload.Add(OpenIdConnectConstants.Metadata.ResponseModesSupported, JArray.FromObject(notification.ResponseModes.Distinct())); payload.Add(OpenIdConnectConstants.Metadata.ResponseTypesSupported, JArray.FromObject(notification.ResponseTypes.Distinct())); payload.Add(OpenIdConnectConstants.Metadata.SubjectTypesSupported, JArray.FromObject(notification.SubjectTypes.Distinct())); payload.Add(OpenIdConnectConstants.Metadata.ScopesSupported, JArray.FromObject(notification.Scopes.Distinct())); payload.Add(OpenIdConnectConstants.Metadata.IdTokenSigningAlgValuesSupported, JArray.FromObject(notification.SigningAlgorithms.Distinct())); var context = new ApplyConfigurationResponseContext(Context, Options, payload); await Options.Provider.ApplyConfigurationResponse(context); if (context.HandledResponse) { return(true); } else if (context.Skipped) { return(false); } using (var buffer = new MemoryStream()) using (var writer = new JsonTextWriter(new StreamWriter(buffer))) { payload.WriteTo(writer); writer.Flush(); Response.ContentLength = buffer.Length; Response.ContentType = "application/json;charset=UTF-8"; buffer.Seek(offset: 0, loc: SeekOrigin.Begin); await buffer.CopyToAsync(Response.Body, 4096, Request.CallCancelled); return(true); } }