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

当我在 /token 索要我的令牌时

  1. 将 WindowsPrincipal 从 OWIN 上下文中拉出

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

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

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

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

  1. 将 JWT 持有者令牌转换回 ClaimsIdentity

  2. 使用该索赔认可来授权通过角色向资源提出请求

  3. 这样,我就不必在每个请求上进行数据库查找以查找用户角色。它刚刚被纳入 JWT 中。

我想我已经正确设置了一切。我的 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。为什么在这种情况下它是空的?难道我做错了什么?

有帮助吗?

解决方案

交换 UseOAuthAuthorizationServer 和 UseOAuthBearerAuthentication 的顺序。UseOAuthBearerAuthentication 调用 UseStageMarker(PipelineStage.Authenticate); 使其(以及它之前的所有内容)在 ASP.NET 管道中更早运行。当您在身份验证阶段运行时,用户为空。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top