I get “Authorization has been denied for this requ

2019-01-23 02:12发布

问题:

I am attempting to decouple my auth and resource server. I am following the example provided in this tutorial:

http://bitoftech.net/2014/09/24/decouple-owin-authorization-server-resource-server-oauth-2-0-web-api/

This is the code in my Startup.cs in my auth server:

using Microsoft.Owin;
using Microsoft.Owin.Security.OAuth;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace AuthServer.Web
{
   public class Startup
   {
      public void Configuration(IAppBuilder app) {
         ConfigureOAuth(app);
      }

      public void ConfigureOAuth(IAppBuilder app)
      {
         OAuthAuthorizationServerOptions 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());

      }
   }
}

This is the startup.cs in my resource server (i.e. my sample Web api application):

using Microsoft.Owin.Security.OAuth;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace AuthTestApi.Web
{
   public class Startup
   {
      public void Configuration(IAppBuilder app)
      {
         app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
         app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
      }      
   }
}

When I post the following request to the "\token" endpoint of my auth server I sucessfully receive a token:

{
access_token: "PszrzJUtQUhX42GMryWjZiVHuKiJ9yCVH_1tZURumtC5mTj2tpuRDF3tXcN_VNIYuXY40IG0K7W3KASfJ9DlNIU2jMOkL2U5oEAXLNRRQuNYdEJ7dMPb14nW19JIaM4BMk00xfQ8MFRw0p6-uoh0-e-Q6iAiTwDNN3F7bYMF9qm874qhLWEcOt6dWQgwpdDUVPDi7F07-Ck0zAs48Dg5w4q93vDpFaQMrziJg9aaxN8",
token_type: "bearer",
expires_in: 86399
}

When I post the following request to my controller I receive the "Authorization has been denied for this request" error message?

GET /api/Test HTTP/1.1
Host: localhost:63305
Accept: application/json
Content-Type: application/json
Authorization: Bearer PszrzJUtQUhX42GMryWjZiVHuKiJ9yCVH_1tZURumtC5mTj2tpuRDF3tXcN_VNIYuXY40IG0K7W3KASfJ9DlNIU2jMOkL2U5oEAXLNRRQuNYdEJ7dMPb14nW19JIaM4BMk00xfQ8MFRw0p6-uoh0-e-Q6iAiTwDNN3F7bYMF9qm874qhLWEcOt6dWQgwpdDUVPDi7F07-Ck0zAs48Dg5w4q93vDpFaQMrziJg9aaxN8
Cache-Control: no-cache
Postman-Token: aeca8515-70b1-ef2c-f317-bf66136dccab

My auth server and resource / web api projects are in different solutions and are running on different ports (...not sure if that matters but thought Id mention it).

At this point these 2 projects are making use of oAuth OWIN middleware (and has very little custom code). The middleware is blackbox somewhat and just need some assistance in figuring out why I am receiving this error message.

Also note that the I am running both servers in two Visual Studio 2013 Web application projects that are in different VS 2013 solutions that are running on different ports. I am not sure if that matters but thought I would mention it.

Thanks in advance.

回答1:

I was facing exactly the same problem in the last couple of days, although I host both application on the same machine (different ports) but it didn't work without adding machine key both web.config files and make sure that the same packages version number installed in both applications



回答2:

I just came across the same problem and found the solution:

You need to register the OAuth Token Generator and OAuth Token Consumer things before WebAPI is registered.

Kind of makes sense if you think of this as a pipeline, where Authentication/Authorization should come before any request handling by the controllers.

TL;DR: Change

appBuilder.UseWebApi(config);

this.ConfigureOAuthTokenGenerator(appBuilder);
this.ConfigureOAuthConsumer(appBuilder);

To

this.ConfigureOAuthTokenGenerator(appBuilder);
this.ConfigureOAuthConsumer(appBuilder);

appBuilder.UseWebApi(config);


回答3:

I was also receiving the error message 'Authorization has been denied for this request', although I don't have separate auth and resource servers.

I am using Ninject's OwinHost and had it configured in Startup before configuring OAuth, as follows:

public void Configuration(IAppBuilder app)
{
    var config = new HttpConfiguration();

    app.UseNinjectMiddleware(() =>
    {
        var kernel = new StandardKernel();
        kernel.Load(Assembly.GetExecutingAssembly());
        return kernel;
    }).UseNinjectWebApi(config);

    ConfigureOAuth(app);

    WebApiConfig.Register(config);
    app.UseCors(CorsOptions.AllowAll);
    app.UseWebApi(config);
}

I found that moving the Ninject configuration to the end resolved the problem, like so:

public void Configuration(IAppBuilder app)
{
    var config = new HttpConfiguration();

    ConfigureOAuth(app);

    WebApiConfig.Register(config);
    app.UseCors(CorsOptions.AllowAll);
    app.UseWebApi(config);

    app.UseNinjectMiddleware(() =>
    {
        var kernel = new StandardKernel();
        kernel.Load(Assembly.GetExecutingAssembly());
        return kernel;
    }).UseNinjectWebApi(config);
}

Maybe your problem is to do with the startup order of your middleware.



回答4:

In my post I was clear that you need to override the machineKey node for both APIs (Authorization Server and Resource Server) and share the same machineKey between both web.config files. How do you host those 2 different projects? they are on the same machine or different machines? Please go back to step 5 from the post and check how you can achieve this.



回答5:

For me, the problem was a mismatched version number in Owin packeges:

 <dependentAssembly>
    <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" />
    <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" />
    <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" />
    <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" />
    <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
  </dependentAssembly>

After updating the required older packages, everything worked like a charm. :)



回答6:

In your OwinStartup class, IAppBuilder.UseOAuthBearerTokens() needs to be called BEFORE IAppBuilder.UseWebApi()

public void Configuration(IAppBuilder app)
{
    app.UseOAuthBearerTokens(...);
    app.UseWebApi(...);
}


回答7:

June 6 2018 update - using the latest WebAPI and OWIN packages. I've been banging my head against this problem for more than I would like to admit. None of the above suggestions worked for me, things suddenly started working once I added a certain project dependency that I wasn't even using in my code: the Microsoft.Owin.Host.SystemWeb NuGet package. This setup is way too finicky and black-boxed for my taste, I don't know why it works like this, but here's what I did.

The minimal setup that I needed for the resource service (the authentication/token service was already setup):

  • add references to Microsoft.Owin.Security.Oauth and Microsoft.Owin.Host.SystemWeb
  • create a startup.cs file with the following content:

    using Microsoft.Owin;
    using Owin;
    using Microsoft.Owin.Security.OAuth;
    
    [assembly: OwinStartup(typeof(MyProject.Startup))]
    
    namespace MyProject
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions{ });
            }
        }
    }
    
  • Add the following to your Web.config file in the <appSettings> section

<add key="owin:appStartup" value="MyProject.Startup" />
  • Add the machineKey entry in your Web.config file in the <system.web> section. If you need to generate it, search around, there is a lot of info on that out there. You can use this as a starting point: http://bitoftech.net/2014/09/24/decouple-owin-authorization-server-resource-server-oauth-2-0-web-api/
  • Add the [Authorize] attribute to your controllers/routes.