Spring Security OAuth2 中的 JwtAccessTokenConverter

发布于:2024-05-21 ⋅ 阅读:(135) ⋅ 点赞:(0)

介绍

JwtAccessTokenConverter 是 Spring Security OAuth2 中的一个类,用于处理 JWT(JSON Web Token)的生成和验证。它在授权服务器和资源服务器之间起着关键作用,确保令牌的完整性和真实性。

JwtAccessTokenConverter 的角色和作用

在授权服务器中

  • JwtAccessTokenConverter 用于生成和签名 JWT。
  • 授权服务器使用私钥对 JWT 进行签名,以确保令牌的完整性和真实性。

在资源服务器中

  • JwtAccessTokenConverter 用于验证和解码 JWT。
  • 资源服务器使用公钥验证 JWT 的签名,以确保令牌未被篡改,并从中提取相关的声明(claims)。

JwtAccessTokenConverter 的具体功能

  1. 令牌转换(Token Conversion)

    • 将 OAuth2 访问令牌转换为 JWT。
    • 将 JWT 解码为 OAuth2 访问令牌。
  2. 签名和验证(Signing and Verification)

    • 在授权服务器中使用私钥对 JWT 进行签名。
    • 在资源服务器中使用公钥验证 JWT 的签名。

授权服务器、资源服务器和 JwtAccessTokenConverter 之间的关系

授权服务器

授权服务器负责认证用户并颁发令牌。配置授权服务器时,会使用 JwtAccessTokenConverter 来生成和签名 JWT。示例配置如下:

import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;

import java.security.KeyPair;

@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        KeyPair keyPair = new KeyStoreKeyFactory(
            new ClassPathResource("cxs-jwt.jks"), "cxs123".toCharArray())
            .getKeyPair("cxs-jwt");
        converter.setKeyPair(keyPair);
        return converter;
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.tokenStore(tokenStore()).accessTokenConverter(accessTokenConverter());
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
    }
}

资源服务器

资源服务器保护资源,并在每个请求中验证 JWT 的有效性。配置资源服务器时,也会使用 JwtAccessTokenConverter 来验证 JWT 的签名。示例配置如下

import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.TokenStore;

import java.io.IOException;
import java.nio.charset.Charset;

public class ResourceConfig extends ResourceServerConfigurerAdapter {

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
        ClassPathResource resource = new ClassPathResource("jwt-publicKey.txt");
        try {
            String publicKey = FileUtil.readString(resource.getFile(), Charset.defaultCharset());
            jwtAccessTokenConverter.setVerifierKey(publicKey);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return jwtAccessTokenConverter;
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenStore(tokenStore());
    }
}

工作流程

  1. 客户端请求令牌

    • 客户端(如 Web 应用或移动应用)向授权服务器请求访问令牌。
    • 授权服务器认证客户端身份,并生成 JWT。
    • JwtAccessTokenConverter 使用私钥对 JWT 进行签名。
    • 签名后的 JWT 返回给客户端。
  2. 客户端请求受保护资源

    • 客户端使用 JWT 请求资源服务器的受保护资源。
    • 资源服务器接收到 JWT,并使用 JwtAccessTokenConverter 进行解码和签名验证。
    • JwtAccessTokenConverter 使用公钥验证 JWT 的签名。
    • 如果签名验证通过,资源服务器允许访问受保护资源;如果验证失败,拒绝访问。

具体方法解释

configure(AuthorizationServerEndpointsConfigurer endpoints)

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
    endpoints.tokenStore(tokenStore()).accessTokenConverter(accessTokenConverter());
}
  • tokenStore(tokenStore())

    • 指定用于存储令牌的策略。在这里使用 JwtTokenStore
    • JwtTokenStore 是一个 TokenStore 的实现,用于存储 JWT。
  • accessTokenConverter(accessTokenConverter())

    • 指定用于访问令牌转换的策略。在这里使用 JwtAccessTokenConverter
    • JwtAccessTokenConverter 用于将 OAuth2 访问令牌转换为 JWT,并在授权服务器中使用私钥对 JWT 进行签名。

configure(AuthorizationServerSecurityConfigurer security)

@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}

这段代码的作用是配置授权服务器的安全性,具体包括以下两方面:

  1. tokenKeyAccess("permitAll()")

    • 允许所有人访问令牌密钥端点。
    • 通常,这个端点提供的是公钥,客户端和资源服务器可以通过这个端点获取公钥,用于验证 JWT 的签名。
    • 公开访问公钥是安全的,因为公钥仅用于验证签名,而不能用于生成签名。
  2. checkTokenAccess("isAuthenticated()")

    • 要求对令牌检查的访问需要身份验证。
    • 这意味着只有经过认证的客户端才能访问检查令牌的端点,确保只有合法的客户端可以进行令牌验证请求。

运行流程

  1. 令牌生成和存储

    • 客户端请求令牌时,授权服务器使用 JwtAccessTokenConverter 生成 JWT,并存储在 JwtTokenStore 中。
  2. 公钥访问

    • 客户端或资源服务器可以访问 /oauth/token_key 端点获取公钥,用于验证 JWT 的签名。
  3. 令牌检查

    • 客户端或资源服务器可以访问 /oauth/check_token 端点检查令牌的有效性,但必须经过身份验证才能访问该端点。

总结

  • configure(AuthorizationServerEndpointsConfigurer endpoints) 配置了授权服务器的端点,指定了如何存储和转换令牌。
  • configure(AuthorizationServerSecurityConfigurer security) 配置了授权服务器的安全性,定义了公钥访问和令牌检查的访问规则。

这些配置确保了授权服务器能够安全地生成和管理 JWT,并提供必要的端点供客户端和资源服务器访问。


网站公告

今日签到

点亮在社区的每一天
去签到