コード例 #1
0
        private async Task <bool> SendPayloadAsync(OpenIdConnectResponse response)
        {
            using (var buffer = new MemoryStream())
                using (var writer = new JsonTextWriter(new StreamWriter(buffer)))
                {
                    var serializer = JsonSerializer.CreateDefault();
                    serializer.Serialize(writer, response);

                    writer.Flush();

                    // Note: when using basic authentication, returning an invalid_client error MUST result in
                    // an unauthorized response but returning a 401 status code would invoke the previously
                    // registered authentication middleware and potentially replace it by a 302 response.
                    // To work around this OWIN/Katana limitation, a 400 response code is always returned.
                    if (!string.IsNullOrEmpty(response.Error))
                    {
                        Response.StatusCode = 400;
                    }

                    Response.ContentLength = buffer.Length;
                    Response.ContentType   = "application/json;charset=UTF-8";

                    switch (response.GetProperty <string>(OpenIdConnectConstants.Properties.MessageType))
                    {
                    // Discovery, userinfo and introspection responses can be cached by the client
                    // or the intermediate proxies. To allow the developer to set up his own response
                    // caching policy, don't override the Cache-Control, Pragma and Expires headers.
                    case OpenIdConnectConstants.MessageTypes.ConfigurationResponse:
                    case OpenIdConnectConstants.MessageTypes.CryptographyResponse:
                    case OpenIdConnectConstants.MessageTypes.IntrospectionResponse:
                    case OpenIdConnectConstants.MessageTypes.UserinfoResponse:
                        break;

                    // Prevent the other responses from being cached.
                    default:
                        Response.Headers["Cache-Control"] = "no-cache";
                        Response.Headers["Pragma"]        = "no-cache";
                        Response.Headers["Expires"]       = "Thu, 01 Jan 1970 00:00:00 GMT";

                        break;
                    }

                    buffer.Seek(offset: 0, loc: SeekOrigin.Begin);
                    await buffer.CopyToAsync(Response.Body, 4096, Request.CallCancelled);

                    // Return true to stop processing the request.
                    return(true);
                }
        }
コード例 #2
0
        private async Task <bool> SendPayloadAsync(OpenIdConnectResponse response)
        {
            using (var buffer = new MemoryStream())
                using (var writer = new JsonTextWriter(new StreamWriter(buffer)))
                {
                    var serializer = JsonSerializer.CreateDefault();
                    serializer.Serialize(writer, response);

                    writer.Flush();

                    if (!string.IsNullOrEmpty(response.Error))
                    {
                        Response.StatusCode = 400;
                    }

                    Response.ContentLength = buffer.Length;
                    Response.ContentType   = "application/json;charset=UTF-8";

                    switch (response.GetProperty <string>(OpenIdConnectConstants.Properties.MessageType))
                    {
                    // Discovery, userinfo and introspection responses can be cached by the client
                    // or the intermediate proxies. To allow the developer to set up his own response
                    // caching policy, don't override the Cache-Control, Pragma and Expires headers.
                    case OpenIdConnectConstants.MessageTypes.ConfigurationResponse:
                    case OpenIdConnectConstants.MessageTypes.CryptographyResponse:
                    case OpenIdConnectConstants.MessageTypes.IntrospectionResponse:
                    case OpenIdConnectConstants.MessageTypes.UserinfoResponse:
                        break;

                    // Prevent the other responses from being cached.
                    default:
                        Response.Headers[HeaderNames.CacheControl] = "no-cache";
                        Response.Headers[HeaderNames.Pragma]       = "no-cache";
                        Response.Headers[HeaderNames.Expires]      = "-1";

                        break;
                    }

                    buffer.Seek(offset: 0, loc: SeekOrigin.Begin);
                    await buffer.CopyToAsync(Response.Body, 4096, Context.RequestAborted);

                    // Return true to stop processing the request.
                    return(true);
                }
        }
コード例 #3
0
        private async Task <bool> SendPayloadAsync(OpenIdConnectResponse response)
        {
            using (var buffer = new MemoryStream())
                using (var writer = new JsonTextWriter(new StreamWriter(buffer)))
                {
                    var serializer = JsonSerializer.CreateDefault();
                    serializer.Serialize(writer, response);

                    writer.Flush();

                    if (!string.IsNullOrEmpty(response.Error))
                    {
                        // When client authentication is made using basic authentication, the authorization server MUST return
                        // a 401 response with a valid WWW-Authenticate header containing the Basic scheme and a non-empty realm.
                        // A similar error MAY be returned even when basic authentication is not used and MUST also be returned
                        // when an invalid token is received by the userinfo endpoint using the Bearer authentication scheme.
                        // To simplify the logic, a 401 response with the Bearer scheme is returned for invalid_token errors
                        // and a 401 response with the Basic scheme is returned for invalid_client, even if the credentials
                        // were specified in the request form instead of the HTTP headers, as allowed by the specification.
                        string GetAuthenticationScheme()
                        {
                            switch (response.Error)
                            {
                            case OpenIdConnectConstants.Errors.InvalidClient: return(OpenIdConnectConstants.Schemes.Basic);

                            case OpenIdConnectConstants.Errors.InvalidToken:  return(OpenIdConnectConstants.Schemes.Bearer);

                            default:                                          return(null);
                            }
                        }

                        var scheme = GetAuthenticationScheme();
                        if (!string.IsNullOrEmpty(scheme))
                        {
                            Response.StatusCode = 401;

                            Response.Headers[HeaderNames.WWWAuthenticate] = new StringBuilder()
                                                                            .Append(scheme)
                                                                            .Append(' ')
                                                                            .Append(OpenIdConnectConstants.Parameters.Realm)
                                                                            .Append("=\"")
                                                                            .Append(Context.GetIssuer(Options))
                                                                            .Append('"')
                                                                            .ToString();
                        }

                        else
                        {
                            Response.StatusCode = 400;
                        }
                    }

                    Response.ContentLength = buffer.Length;
                    Response.ContentType   = "application/json;charset=UTF-8";

                    switch (response.GetProperty <string>(OpenIdConnectConstants.Properties.MessageType))
                    {
                    // Discovery, userinfo and introspection responses can be cached by the client
                    // or the intermediate proxies. To allow the developer to set up his own response
                    // caching policy, don't override the Cache-Control, Pragma and Expires headers.
                    case OpenIdConnectConstants.MessageTypes.ConfigurationResponse:
                    case OpenIdConnectConstants.MessageTypes.CryptographyResponse:
                    case OpenIdConnectConstants.MessageTypes.IntrospectionResponse:
                    case OpenIdConnectConstants.MessageTypes.UserinfoResponse:
                        break;

                    // Prevent the other responses from being cached.
                    default:
                        Response.Headers[HeaderNames.CacheControl] = "no-cache";
                        Response.Headers[HeaderNames.Pragma]       = "no-cache";
                        Response.Headers[HeaderNames.Expires]      = "Thu, 01 Jan 1970 00:00:00 GMT";

                        break;
                    }

                    buffer.Seek(offset: 0, loc: SeekOrigin.Begin);
                    await buffer.CopyToAsync(Response.Body, 4096, Context.RequestAborted);

                    // Return true to stop processing the request.
                    return(true);
                }
        }