API end point returning “Authorization has been denied for this request.” when sending bearer token

让人想犯罪 __ 提交于 2021-02-05 23:17:13

问题


I've followed a tutorial to protect a Web API with OAuth in C#.

I'm doing some tests and so far I've been able to get the access token successfully from /token. I'm using a Chrome extension called "Advanced REST Client" to test it.

{"access_token":"...","token_type":"bearer","expires_in":86399}

This is what I get back from /token. Everything looks good.

My next request is to my test API Controller:

namespace API.Controllers
{
    [Authorize]
    [RoutePrefix("api/Social")]
    public class SocialController : ApiController
    {
      ....


        [HttpPost]
        public IHttpActionResult Schedule(SocialPost post)
        {
            var test = HttpContext.Current.GetOwinContext().Authentication.User;

            ....
            return Ok();
        }
    }
}

The request is a POST and has the header:

Authorization: Bearer XXXXXXXTOKEHEREXXXXXXX

I get: Authorization has been denied for this request. returned in JSON.

I tried doing a GET as well and I get what I would expect, that the method isn't supported since I didn't implement it.

Here is my Authorization Provider:

public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
    public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
    }

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {

        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

        using (var repo = new AuthRepository())
        {
            IdentityUser user = await repo.FindUser(context.UserName, context.Password);

            if (user == null)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect.");
                return;
            }
        }

        var identity = new ClaimsIdentity(context.Options.AuthenticationType);
        identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
        identity.AddClaim(new Claim(ClaimTypes.Role, "User"));

        context.Validated(identity); 

    }
}

Any help would be great. I'm not sure if it is the request or the code that is wrong.

edit: Here is my Startup.cs

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();
        WebApiConfig.Register(config);
        app.UseWebApi(config);
        ConfigureOAuth(app);
    }

    public void ConfigureOAuth(IAppBuilder app)
    {
        var oAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            Provider = new SimpleAuthorizationServerProvider()
        };

        // Token Generation
        app.UseOAuthAuthorizationServer(oAuthServerOptions);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

    }
}

回答1:


Issue is pretty simple: Change order of your OWIN pipeline.

public void Configuration(IAppBuilder app)
{
    ConfigureOAuth(app);
    var config = new HttpConfiguration();
    WebApiConfig.Register(config);
    app.UseWebApi(config);
}

For OWIN pipeline order of your configuration quite important. In your case, you try to use your Web API handler before the OAuth handler. Inside of it, you validate your request, found you secure action and try to validate it against current Owin.Context.User. At this point this user not exist because its set from the token with OAuth Handler which called later.




回答2:


You have to add a claim with this schema:

http://schemas.microsoft.com/ws/2008/06/identity/claims/role

best thing to do is to use the pre-defined set of claims:

identity.AddClaim(new Claim(ClaimTypes.Role, "User"));

You can find ClaimTypes in System.Security.Claims.

Another thing you have to consider is filter roles in your Controller/Action:

[Authorize(Roles="User")]

You can find a simple sample app, self-hosted owin with a jquery client here.




回答3:


Looks like the version of "System.IdentityModel.Tokens.Jwt" that co-exists with the other Owin assemblies is not proper.

In case you're using "Microsoft.Owin.Security.Jwt" version 2.1.0, you ought to be using the "System.IdentityModel.Tokens.Jwt" assembly of version 3.0.2.

From the package manager console, try:

Update-Package System.IdentityModel.Tokens.Jwt -Version 3.0.2


来源:https://stackoverflow.com/questions/27912003/api-end-point-returning-authorization-has-been-denied-for-this-request-when-s

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