如何使用 OWIN OAuthBearerAuthentication 验证访问令牌?

Posted

技术标签:

【中文标题】如何使用 OWIN OAuthBearerAuthentication 验证访问令牌?【英文标题】:How to authenticate an access token using OWIN OAuthBearerAuthentication? 【发布时间】:2014-09-25 15:50:35 【问题描述】:

我想要什么:

    令牌生成器使用 OAuthAuthorizationServer,令牌消费者使用 OAuthBearerAuthentication(验证访问令牌)。 使用 OWIN 管道管理所有内容、令牌内容和 Web api 内容。

代码呢:

public void Configuration(IAppBuilder app)

    app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
    
        AuthorizeEndpointPath = "/Authorize",
        AllowInsecureHttp = true,
        Provider = new OAuthAuthorizationServerProvider 
        
            OnGrantCustomExtension = GrantCustomExtension,
            OnValidateClientRedirectUri = ValidateClientRedirectUri,
            OnValidateClientAuthentication = ValidateClientAuthentication,
        
    );

    app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
    
        Provider = new OAuthBearerAuthenticationProvider 
         
            //Handles applying the authentication challenge to the response message.
            ApplyChallenge=MyApplyChallenge,

            //Handles processing OAuth bearer token.
            RequestToken=MyRequestToken,

            //Handles validating the identity produced from an OAuth bearer token.
            ValidateIdentity = MyValidateIdentity,
        
    );

    app.UseWebApi(new WebApplication3.Config.MyWebApiConfiguration());

问题是什么:

    OAuthBearerAuthenticationProvider的3个属性, ApplyChallengeRequestTokenValidateIdentity。如何 实现这3种方法?

    在令牌认证过程中,我的想法是解密访问令牌,从客户端验证令牌,如果令牌被验证,则将令牌的身份放入HttpContext.Current.User

    OAuthBearerAuthenticationProvider 的职责是履行 前面的步骤。我说的对吗?

【问题讨论】:

你在ASP网站上用过walkthrough吗? @MatthewHaugen 绝对是,但他们没有提到 OAuthBearerAuthenticationProvider 中的 3 个方法 请问您为什么要实现它们呢?我的意思是不要误会我的意思,总是知道你所有的选择是件好事。我只是好奇你为什么要在你的情况下覆盖默认行为,这听起来不像你需要任何不寻常的东西。 @MatthewHaugen 官方owin中间件的文档很差。 :( 你的意思是中间件已经为我做了解密、验证和放置 Principal @_@ ? 如果您遵循该演练,您将获得一个有效的实现。所以是的。在那之后你可能想做其他的事情,但我会首先得到演练所说的工作。但是,是的,我当然同意文档还有待改进。 【参考方案1】:

如您所知,UseOAuthAuthorizationServer 负责对用户进行身份验证。然后,UseOAuthBearerAuthentication 负责确保只有经过身份验证的用户才能访问您的应用程序。通常,这两个作业被分配给不同的 Web 应用程序。看起来您的应用程序正在同时执行这两种操作。

在某些情况下,您需要覆盖默认的OAuthBearerAuthenticationProvider。也许你知道,或者你不知道在我的情况下,ApplicationCookie 不太适合这个场景。因此,我将第 3 方 JWT 令牌存储在 cookie 中,而不是标头中,并使用它来指示用户已通过 Web 应用程序的身份验证。我还需要重定向到我自己的登录页面,而不是提供 401。

这是一个兼具两者的实现:

public class CustomOAuthBearerProvider : IOAuthBearerAuthenticationProvider

    public Task ApplyChallenge(OAuthChallengeContext context)
    
        context.Response.Redirect("/Account/Login");
        return Task.FromResult<object>(null);
    

    public Task RequestToken(OAuthRequestTokenContext context)
    
        string token = context.Request.Cookies[SessionKey];
        if (!string.IsNullOrEmpty(token))
        
            context.Token = token;
        
        return Task.FromResult<object>(null);
    
    public Task ValidateIdentity(OAuthValidateIdentityContext context)
    
        return Task.FromResult<object>(null);
    

我不需要在ValidateIdentity中做任何特别的事情,但我需要满足接口。

要将其连接起来,请告诉您的应用将 JwtBearerAuthentication 与您的提供程序一起使用:

// controllers with an [Authorize] attribute will be validated with JWT
app.UseJwtBearerAuthentication(
    new JwtBearerAuthenticationOptions
    
        AllowedAudiences = audiences.ToArray(),
        IssuerSecurityTokenProviders = providers.ToArray(),
        Provider = new CookieOAuthBearerProvider()
    
);

【讨论】:

如果我必须添加服务器未提供的特定于应用程序的声明(外部登录,如 Azure AD),是否可以在 ValidateIdnetity 中添加此声明?如果经过身份验证的用户虽然属于组织的一部分,但无权访问应用程序,我应该在哪里向他发送 401 状态? @AJ Morris,您将如何使用 OAuthBearerAuthenticationProvider 覆盖令牌验证?有没有办法做到这一点? 我猜Provider = new CookieOAuthBearerProvider() 应该是Provider = new CustomOAuthBearerProvider() 如何在 ASP.NET Core 2 中执行此操作?我已经发布了一个关于它的问题:***.com/questions/52184431/… 天哪,requestToken 方法救了我的命。几天来一直把我的头撞在墙上,试图让令牌从cookie中工作。谢谢!!

以上是关于如何使用 OWIN OAuthBearerAuthentication 验证访问令牌?的主要内容,如果未能解决你的问题,请参考以下文章

如何知道 OWIN cookie 何时到期?

OWIN 安全 - 如何实现 OAuth2 刷新令牌

如何使用Owin和Web Api 2在SignalR上配置MessagePack?

如何使用 OWIN Jwt Bearer Authentication 记录身份验证结果

ASP.NET (OWIN) Identity:如何从 Web API 控制器获取 UserID?

owin oauth发送附加参数