使用 OWIN oAuth 中间件(具有单独的身份验证和资源服务器)时收到"Authorization has been denied for this request."错误消息



我正在尝试将身份验证和资源服务器解耦。我遵循本教程中提供的示例:

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

这是我的身份验证服务器中Startup.cs中的代码:

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 xxxxx
   {
      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());
      }
   }
}

这是我的资源服务器(即我的示例Web api应用程序)中的startup.cs:

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);
      }      
   }
}

当我将以下请求发布到";\令牌";我的身份验证服务器的端点我成功地接收到一个令牌:

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

当我向我的控制器发出下面的请求时;该请求的授权已被拒绝";错误消息?

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

我的auth-server和resource/web-api项目位于不同的解决方案中,并在不同的端口上运行(……不确定这是否重要,但我想我会提到这一点)。

目前,这两个项目正在使用oAuth OWIN中间件(并且几乎没有自定义代码)。中间件在某种程度上是黑盒,只需要一些帮助就可以弄清楚为什么我会收到这个错误消息。

还请注意,我正在两个Visual Studio 2013 Web应用程序项目中运行这两个服务器,这两个项目位于不同的VS 2013解决方案中,在不同的端口上运行。我不确定这是否重要,但我想我会提到它。

提前谢谢。

我刚刚遇到了同样的问题,并找到了解决方案:

在注册WebAPI之前,您需要注册OAuth Token Generator和OAuth Token Consumer。

如果您认为这是一个管道,那么在控制器处理任何请求之前都应该先进行身份验证/授权,这是有意义的。

TL;DR:更改

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

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

我也收到了错误消息"此请求的授权已被拒绝",尽管我没有单独的身份验证和资源服务器。

我正在使用Ninject的OwinHost,并在配置OAuth之前在Startup中对其进行了配置,如下所示:

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);
}

我发现将Ninject配置移动到最后解决了问题,就像这样:

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);
}

也许您的问题与中间件的启动顺序有关。

过去几天我面临着完全相同的问题,尽管我在同一台机器上(不同的端口)托管了两个应用程序,但如果不添加机器密钥(web.config文件),它就无法工作,请确保两个应用中安装了相同的包版本号

在我的文章中,我清楚地知道您需要覆盖两个API的machineKey节点(授权服务器和资源服务器),并在两个web.config文件之间共享相同的machineKey。你是如何主持这两个不同的项目的?他们在同一台机器上还是在不同的机器上?请回到帖子的第5步,检查如何实现这一点。

对我来说,问题是Owin包中的版本号不匹配:

 <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>

在更新了所需的旧包后,一切都像一个魅力。:)

2018年6月6日更新-使用最新的WebAPI和OWIN包。我一直在思考这个问题,我不愿意承认。上述建议对我都不起作用,当我添加了一个我甚至没有在代码中使用的特定项目依赖项时,事情突然开始起作用:Microsoft.Owin.Host.SystemWeb NuGet包。这个设置太挑剔了,而且黑盒不适合我的口味,我不知道为什么它会这样工作,但我是这么做的。

资源服务所需的最小设置(身份验证/令牌服务已经设置):

  • 添加对Microsoft.Owin.Security.OauthMicrosoft.Owin.Host.SystemWeb的引用
  • 创建一个包含以下内容的startup.cs文件:

    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{ });
            }
        }
    }
    
  • 将以下内容添加到<appSettings>部分中的Web.config文件中

<add key="owin:appStartup" value="MyProject.Startup" />
  • <system.web>部分的Web.config文件中添加machineKey条目。如果你需要生成它,四处搜索,有很多关于它的信息。您可以将此作为起点:http://bitoftech.net/2014/09/24/decouple-owin-authorization-server-resource-server-oauth-2-0-web-api/
  • [Authorize]属性添加到控制器/路由中

在OwinStartup类中,需要在IAppBuilder.UseWebApi()之前调用IAppBuilder.UseOAuthBearerTokens()

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

在IIS中使用不同的池运行web应用程序,您将获得不同的密钥。因此,您应该使用相同的应用程序池运行身份验证和资源应用程序。检查这个https://gyorgybalassy.wordpress.com/2013/12/07/how-unique-is-your-machine-key/

相关内容

最新更新