如何在 Web API 中验证 access_token(Azure AD OAuth 2.0)?

Bhu*_*han 8 oauth oauth-2.0 azure-active-directory spring-boot

我正在将 Azure AD OAuth 2.0 授权流程用于 Spring Boot 微服务 + Angular2 应用程序。
我的申请流程

  1. (从前端对我的 Spring Boot 应用程序的第一个请求)Spring Boot 应用程序将它重定向到 Azure 登录页面。
  2. 用户输入他的凭据
  3. 授权服务器向 发送 POST 请求redirect_uri,该请求authorization_code包含其他用户信息(如名字、姓氏和用户 ID)。
  4. 然后我得到bearer令牌并refresh_token使用authorization_code

现在我想发送bearer_token到其他微服务来验证bearer_token.

我的问题是如何bearer_token在其他微服务中验证和检索该令牌的所有者?

oia*_*kyi 6

我假设你使用 Azure AD OAuth 2.0 的默认配置,该配置返回 JWT 编码的令牌。这种类型的令牌没有什么好处 - 您可以从令牌本身提取诸如授予范围之类的信息,并且可以通过检查令牌签名来避免向授权服务器发送验证请求。

配置 JWT 令牌验证

您需要配置资源服务器(您的 Web API)才能使用 JWT 令牌:

@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(ResourceServerSecurityConfigurer config) {
        config.tokenServices(tokenServices());
    }
 
    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }
 
    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setVerifierKey(obtainAzureADPublicKey());
        return converter;
    }
 
    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        return defaultTokenServices;
    }
 }
Run Code Online (Sandbox Code Playgroud)

此代码(经过少量修改)取自Eugen Paraschiv(又名 Baeldung)的优秀博客文章。

获取 Azure 签名密钥

您需要获取一个非对称公共加密密钥,Azure AD 使用该密钥对已颁发的令牌进行签名并从该obtainAzureADPublicKey方法返回它。

根据文档,您必须首先获取有关 JWT 签名密钥端点的元信息(通过从结果中https://login.microsoftonline.com/common/.well-known/openid-configuration检索属性值)。"jwks_uri"

然后您需要从该 URL 获取正确的密钥。

请注意,Azure AD 会不时更改此信息,因此您不能仅在应用程序启动时执行一次。但是,将其缓存至少 24 小时是一个好主意。