context.Request.User在OWIN OAuthAuthorizationServerProvider中为null

时间:2014-07-30 17:02:12

标签: iis oauth owin asp.net-web-api2

我尝试使用OWIN为我的本地Intranet上的Web API v2端点实施OAuth。 API使用内置Windows身份验证托管在IIS中。简而言之,这就是我想要发生的事情。

当我在/ token

请求我的令牌时
  1. 将WindowsPrincipal拉出OWIN上下文

  2. 使用WindowsPrincipal中的SID为此查找某些角色 用户在SQL表中。

  3. 创建一个存储用户名和角色的新ClaimsIdentity

  4. 将其转换为我发送bak的Json Web令牌(JWT)

  5. 当我使用我的令牌从我的API请求资源时

    1. 将JWT Bearer令牌转换回ClaimsIdentity

    2. 使用ClaimsIdentity来授权对资源的请求 作用

    3. 这样我就不必对每个用户角色进行数据库查找 请求。它刚刚融入JWT。

    4. 我想我正确地设置了一切。我的Startup.Configuration方法看起来像这样。

      public void Configuration(IAppBuilder app)
      {
      
          // token generation
          // This is what drives the action when a client connects to the /token route
          app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
          {
              // for demo purposes
              AllowInsecureHttp = true,
      
              TokenEndpointPath = new PathString("/token"),
              AccessTokenExpireTimeSpan = TimeSpan.FromHours(8),
              AccessTokenFormat = GetMyJwtTokenFormat(),
              Provider = new MyAuthorizationServerProvider()
          });
      
      
      
          //// token consumption
          app.UseOAuthBearerAuthentication(
              new OAuthBearerAuthenticationOptions()
              {
                  Realm = "http://www.ccl.org",
                  Provider = new OAuthBearerAuthenticationProvider(),
                  AccessTokenFormat = GetMyJwtTokenFormat()
              }
          );
      
      
          app.UseWebApi(WebApiConfig.Register());
      
      }
      

      MyAuthorizationServerProvider看起来像这样......

          public class MyAuthorizationServerProvider : OAuthAuthorizationServerProvider
          {
      
              public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
              {
      
                  // Since I'm hosting in IIS with Windows Auth enabled
                  // I'm expecting my WindowsPrincipal to be here, but it's null  :(
                  var windowsPrincipal = context.OwinContext.Request.User.Identity;
      
                  // windowsPrincipal is null here.  Why?
      
                  // Call SQL to get roles for this user
      
                  // create the identity with the roles
                  var id = new ClaimsIdentity(stuff, more stuff);
      
                  context.Validated(id);
              }
          }
      
      

      我的问题是context.Request.User在这里为空。我无法访问我的WindowsPrincipal。如果我创建一些其他虚拟中间件,我可以毫无问题地进入WindowsPrincipal。为什么在这种情况下它为空?我做错了吗?

1 个答案:

答案 0 :(得分:12)

交换UseOAuthAuthorizationServer和UseOAuthBearerAuthentication的顺序。使用OAuthBearerAuthentication调用UseStageMarker(PipelineStage.Authenticate);使其(以及之前的所有内容)在ASP.NET管道中运行。在Authenticate阶段运行时,User为null。