首页 文章

当使用OWIN oAuth中间件(带有单独的Auth和Resource Server)时,我收到“此请求已被拒绝授权 . ”错误消息

提问于
浏览
23

我试图解耦我的身份验证和资源服务器 . 我按照本教程中提供的示例进行操作:

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

这是我的auth服务器中的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 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());

      }
   }
}

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

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

当我将以下请求发布到我的auth服务器的“\ token” endpoints 时,我成功地收到了一个令牌:

{
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服务器和资源/ web api项目在不同的解决方案中,并且在不同的端口上运行(...不确定这是否重要,但我认为Id提到它) .

此时,这两个项目正在使用oAuth OWIN中间件(并且只有很少的自定义代码) . 中间件有点黑盒子,只需要一些帮助来弄清楚我收到此错误消息的原因 .

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.

提前致谢 .

7 回答

  • 23

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

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

    我在过去几天遇到了完全相同的问题,虽然我在同一台机器上安装了两个应用程序(不同的端口)但是如果没有 adding machine key both web.config filesmake sure 它在两个应用程序中都安装了相同的软件包版本号就无法运行

  • 14

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

    在注册WebAPI之前,您需要注册OAuth令牌生成器和OAuth令牌使用者的东西 .

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

    TL; DR:改变

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

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

    虽然我没有单独的身份验证和资源服务器,但我还收到错误消息“此请求已被拒绝授权” .

    我正在使用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);
    }
    

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

  • 4

    在我的帖子中,我很清楚你需要覆盖两个API(授权服务器和资源服务器)的machineKey节点,并在两个web.config文件之间共享相同的machineKey . 你如何举办这两个不同的项目?他们在同一台机器或不同的机器上?请从帖子返回第5步,检查如何实现这一目标 .

  • 1

    对我来说,问题是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>
    

    更新所需的旧包后,一切都像魅力一样 . :)

  • 1

    June 6 2018 update - 使用最新的WebAPI和OWIN包 . 我一直在反对这个问题,而不是我想承认 . 以上建议都没有对我有用, things suddenly started working once I added a certain project dependency 我甚至没有在我的代码中使用: the Microsoft.Owin.Host.SystemWeb NuGet package . 根据我的口味,这个设置太挑剔和黑盒子,我不会做我做的 .

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

    • 添加对 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" />
    

相关问题