OWIN OAuthAuthorizationServerProvider 中的 context.Request.User 为 null
-
21-12-2019 - |
题
我正在尝试使用 OWIN 为本地 Intranet 上的 Web API v2 端点实现 OAuth。该 API 使用内置 Windows 身份验证托管在 IIS 中。简而言之,这就是我想要发生的事情。
当我在 /token 索要我的令牌时
将 WindowsPrincipal 从 OWIN 上下文中拉出
使用WindowsPrincipal中的SID在SQL表中查找该用户的某些角色。
创建一个新的 ClaimsIdentity 来存储用户名和角色
将其转换为我发送的 Json Web 令牌 (JWT)
当我使用我的令牌从 API 请求资源时
将 JWT 持有者令牌转换回 ClaimsIdentity
使用该索赔认可来授权通过角色向资源提出请求
这样,我就不必在每个请求上进行数据库查找以查找用户角色。它刚刚被纳入 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 管道中更早运行。当您在身份验证阶段运行时,用户为空。