AspNet.Security.OAuth.Extensions Error while introspection

北战南征 提交于 2019-12-24 19:08:06

问题


I'am writing a test application with asp.net core 2.0, AspNet.Security.OpenIdConnect.Server and AspNet.Security.OAuth.Extensions. I ran into a problem with introspection of the access token. When I get my token from /connect/token and send it to my resource server I get the following errors in my server:

fail: AspNet.Security.OpenIdConnect.Server.OpenIdConnectServerHandler[0]
      The introspection request was rejected with the following error: invalid_request ; (null)
info: AspNet.Security.OpenIdConnect.Server.OpenIdConnectServerHandler[0]
      The introspection response was successfully returned: {
        "error": "invalid_request"
      }

And in my resource server:

fail: AspNet.Security.OAuth.Introspection.OAuthIntrospectionHandler[0]
      An error occurred while validating an access token: the remote server returned a BadRequest response with the following payload: Date: Sat, 21 Oct 2017 17:11:50 GMT
      Server: Kestrel
       {"error":"invalid_request"}.
info: AspNet.Security.OAuth.Introspection.OAuthIntrospectionHandler[7]
      Bearer was not authenticated. Failure message: Authentication failed because the authorization server rejected the access token.

This is ConfigureServices method from my Startup class of my resource server (WebApi):

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication().AddOAuthIntrospection(
        options =>
        {
            options.Authority = new Uri("http://localhost:64855/");
            options.Audiences.Add("resource_server");
            options.ClientId = "client_id";
            options.ClientSecret = "client_secret";
            options.RequireHttpsMetadata = false;
        });
    services.AddMvc();
}

This is my protected by AuthorizeAttribute controller in resource server:

[Route("api/[controller]")]
[Authorize(AuthenticationSchemes = OAuthIntrospectionDefaults.AuthenticationScheme)]
public class ValuesController : Controller
{
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] {"value1", "value2"};
    }
}

This is Startup class in auth server:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(
                options =>
                {
                    options.DefaultScheme = OAuthValidationDefaults.AuthenticationScheme;
                })
            .AddOAuthValidation(
                options =>
                {
                    options.Audiences.Add("resource_server");
                });

        services.AddAuthentication().AddOpenIdConnectServer(options =>
        {
            options.TokenEndpointPath = "/connect/token";
            options.IntrospectionEndpointPath = "/connect/introspect";
            options.AllowInsecureHttp = true;
            options.ApplicationCanDisplayErrors = true;
            options.Provider.OnValidateTokenRequest = context =>
            {
                if (!context.Request.IsPasswordGrantType() && !context.Request.IsRefreshTokenGrantType())
                {
                    context.Reject(
                        error: OpenIdConnectConstants.Errors.UnsupportedGrantType,
                        description: "Only grant_type=password and refresh_token " +
                                     "requests are accepted by this server.");

                    return Task.CompletedTask;
                }

                if (string.Equals(context.ClientId, "client_id", StringComparison.Ordinal) &&
                    string.Equals(context.ClientSecret, "client_secret", StringComparison.Ordinal))
                {
                    context.Validate();
                }

                return Task.CompletedTask;
            };

            options.Provider.OnHandleTokenRequest = context =>
            {
                if (context.Request.IsPasswordGrantType())
                {
                    if (!string.Equals(context.Request.Username, "Bob", StringComparison.Ordinal) ||
                        !string.Equals(context.Request.Password, "P@ssw0rd", StringComparison.Ordinal))
                    {
                        context.Reject(
                            error: OpenIdConnectConstants.Errors.InvalidGrant,
                            description: "Invalid user credentials.");

                        return Task.CompletedTask;
                    }

                    var identity = new ClaimsIdentity(context.Scheme.Name,
                        OpenIdConnectConstants.Claims.Name,
                        OpenIdConnectConstants.Claims.Role);

                    identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "[unique id]");

                    identity.AddClaim("urn:customclaim", "value",
                        OpenIdConnectConstants.Destinations.AccessToken,
                        OpenIdConnectConstants.Destinations.IdentityToken);

                    var ticket = new AuthenticationTicket(
                        new ClaimsPrincipal(identity),
                        new AuthenticationProperties(),
                        context.Scheme.Name);

                    ticket.SetScopes(
                        OpenIdConnectConstants.Scopes.Profile,
                        OpenIdConnectConstants.Scopes.OfflineAccess);

                    context.Validate(ticket);
                }

                return Task.CompletedTask;
            };
        });

        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();
        app.UseAuthentication();
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

It seems to me that I somewhere missed something when configuring the server and the client, but I can not understand where. Or maybe I'm just doing something wrong. Maybe, I should implement introspect method by myself... don't know( I already tried to override methods in OpenIdServerConnectProvider, but nothing happened in the end.

Tell me please what can be the problem or what I did wrong. Thanks.

UPD: after all fixes, thanks to Pinpoint, this is my working solution: https://github.com/mstya/Introspection.Sample I hope it helps someone.


回答1:


Or maybe I'm just doing something wrong. Maybe, I should implement introspect method by myself... don't know( I already tried to override methods in OpenIdServerConnectProvider, but nothing happened in the end.

You forgot to implement the ValidateIntrospectionRequest event. Just like ValidateTokenRequest, you have to validate the client credentials and call context.Validate() if they are valid.



来源:https://stackoverflow.com/questions/46866209/aspnet-security-oauth-extensions-error-while-introspection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!