Spring Cloud Security的核心组件-OAuth2示例

2023-04-13 07:03:55 浏览数 (2)

Spring Cloud Security 的 OAuth2 示例

下面我们通过一个基于 Spring Cloud Security 的 OAuth2 示例来演示 OAuth2 的工作流程。

添加依赖

在 pom.xml 文件中添加以下依赖:

代码语言:javascript复制
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>

配置授权服务器

在授权服务器中,我们需要配置客户端信息、用户信息和端点信息等。下面是一个示例:

代码语言:javascript复制
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private ClientDetailsService clientDetailsService;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private JwtAccessTokenConverter accessTokenConverter;

    @Value("${jwt.clientId:client}")
    private String clientId;

    @Value("${jwt.client-secret:secret}")
    private String clientSecret;

    @Value("${jwt.accessTokenValidititySeconds:43200}") // 12 hours
    private int accessTokenValiditySeconds;

    @Value("${jwt.authorizedGrantTypes:password,refresh_token}")
    private String[] authorizedGrantTypes;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient(clientId)
                .secret(clientSecret)
                .authorizedGrantTypes(authorizedGrantTypes)
                .scopes("read", "write")
                .accessTokenValiditySeconds(accessTokenValiditySeconds);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager)
                .accessTokenConverter(accessTokenConverter)
                .tokenStore(tokenStore)
                .userDetailsService(userDetailsService);
    }

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

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("123456");
        return converter;
    }

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

配置资源服务器

在资源服务器中,我们需要配置访问规则和访问令牌的校验规则等。下面是一个示例:

代码语言:javascript复制
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/api/**").authenticated()
                .anyRequest().permitAll();
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId("resource");
    }
}

在上面的代码中,我们将所有以 /api 开头的请求都设置为需要认证。此外,我们还将资源服务器的资源 ID 设置为 resource。

配置客户端

在客户端中,我们需要配置客户端 ID、客户端密钥、访问令牌 URL 和访问令牌校验 URL 等信息。下面是一个示例:

代码语言:javascript复制
@Configuration
public class ClientConfig {

    @Bean
    public OAuth2RestTemplate oauth2RestTemplate(OAuth2ClientContext oauth2ClientContext) {
        OAuth2ProtectedResourceDetails details = new ClientCredentialsResourceDetails();
        details.setAccessTokenUri("http://localhost:8080/oauth/token");
        details.setClientId("client");
        details.setClientSecret("secret");
        return new OAuth2RestTemplate(details, oauth2ClientContext);
    }
}

在上面的代码中,我们使用 ClientCredentialsResourceDetails 类来配置客户端信息,并使用 OAuth2RestTemplate 类来发送请求和获取访问令牌。

测试 OAuth2

现在我们已经完成了 OAuth2 的配置,下面我们来测试一下它是否可以正常工作。

首先,我们需要使用用户名和密码获取授权码:

代码语言:javascript复制
http://localhost:8080/oauth/authorize?response_type=code&client_id=client&redirect_uri=http://localhost:8081/login/oauth2/code/custom

然后,我们使用授权码获取访问令牌:

代码语言:javascript复制
http://localhost:8080/oauth/token?grant_type=authorization_code&code=[code]&redirect_uri=http://localhost:8081/login/oauth2/code/custom&client_id=client&client_secret=secret

最后,我们使用访问令牌来请求受保护的资源:

代码语言:javascript复制
curl -H "Authorization: Bearer [access_token]" http://localhost:8081/api/test

如果一切正常,我们应该可以看到请求成功返回了受保护的资源。

0 人点赞