https://gitee.com/msxy/qingfeng-springboot-vue3-antdesign-vitehttps://gitee.com/msxy/qingfeng-springboot-vue3-antdesign-vite
org.springframework.boot
spring-boot-starter-security
org.springframework.security.oauth
spring-security-oauth2
2.3.4.RELEASE
org.springframework.security
spring-security-jwt
1.1.1.RELEASE
认证服务器需要创建三大配置:
在认证服务中,tokenStore使用的是RedisTokenStore,认证服务器生成的令牌将被存储到Redis中。此处我们需要引入redis用于存储认证服务的令牌token。
package com.qingfeng.auth.configure;
import com.qingfeng.auth.service.UserDetailServiceImpl;
import com.qingfeng.auth.translator.MyWebResponseExceptionTranslator;
import com.qingfeng.framework.properties.AuthProperties;
import com.qingfeng.framework.properties.ClientsProperties;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.builders.InMemoryClientDetailsServiceBuilder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
/**
* @title: AuthorizationServerConfigure
* @projectName: AuthorizationServerConfigure
* @description: TODO
* @author: Administrator
* @date: 2021/2/21 0021 21:51
*/
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfigure extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Autowired
private UserDetailServiceImpl userDetailService;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private AuthProperties authProperties;
@Autowired
private MyWebResponseExceptionTranslator exceptionTranslator;
// @Override
// public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// clients.inMemory()
// .withClient("qingfeng")
// .secret(passwordEncoder.encode("123456"))
// .authorizedGrantTypes("password", "refresh_token")
// .scopes("all");
// }
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
ClientsProperties[] clientsArray = authProperties.getClients();
InMemoryClientDetailsServiceBuilder builder = clients.inMemory();
if (ArrayUtils.isNotEmpty(clientsArray)) {
for (ClientsProperties client : clientsArray) {
if (StringUtils.isBlank(client.getClient())) {
throw new Exception("client不能为空");
}
if (StringUtils.isBlank(client.getSecret())) {
throw new Exception("secret不能为空");
}
String[] grantTypes = StringUtils.splitByWholeSeparatorPreserveAllTokens(client.getGrantType(), ",");
builder.withClient(client.getClient())
.secret(passwordEncoder.encode(client.getSecret()))
.authorizedGrantTypes(grantTypes)
.scopes(client.getScope())
.accessTokenValiditySeconds(authProperties.getAccessTokenValiditySeconds())
.refreshTokenValiditySeconds(authProperties.getRefreshTokenValiditySeconds());
}
}
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.tokenStore(tokenStore())
.accessTokenConverter(jwtAccessTokenConverter())
.userDetailsService(userDetailService)
.authenticationManager(authenticationManager)
// .tokenServices(defaultTokenServices())
.exceptionTranslator(exceptionTranslator);
}
@Bean
public TokenStore tokenStore() {
// return new RedisTokenStore(redisConnectionFactory);
return new JwtTokenStore(jwtAccessTokenConverter());
}
// @Primary
// @Bean
// public DefaultTokenServices defaultTokenServices() {
// DefaultTokenServices tokenServices = new DefaultTokenServices();
// tokenServices.setTokenStore(tokenStore());
// tokenServices.setSupportRefreshToken(true);
tokenServices.setAccessTokenValiditySeconds(60 * 60 * 24);
tokenServices.setRefreshTokenValiditySeconds(60 * 60 * 24 * 7);
// tokenServices.setAccessTokenValiditySeconds(authProperties.getAccessTokenValiditySeconds());
// tokenServices.setRefreshTokenValiditySeconds(authProperties.getRefreshTokenValiditySeconds());
// return tokenServices;
// }
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
DefaultAccessTokenConverter defaultAccessTokenConverter = (DefaultAccessTokenConverter) accessTokenConverter.getAccessTokenConverter();
DefaultUserAuthenticationConverter userAuthenticationConverter = new DefaultUserAuthenticationConverter();
userAuthenticationConverter.setUserDetailsService(userDetailService);
defaultAccessTokenConverter.setUserTokenConverter(userAuthenticationConverter);
accessTokenConverter.setSigningKey("qingfeng");
return accessTokenConverter;
}
}
我们来介绍下认证服务类,首先@EnableAuthorizationServer表示开始认证服务。而且继承了AuthorizationServerConfigurerAdapter适配器,AuthorizationServerConfigurerAdapter包含了3个方法:
public class AuthorizationServerConfigurerAdapter implements AuthorizationServerConfigurer {
public AuthorizationServerConfigurerAdapter() {
}
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
}
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
}
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
}
}
分别用于配置令牌端点的安全约束、客户端信息、配置令牌端点的安全约束
这也是我们AuthorizationServerConfigure类的骨架,其他代码都是围绕这3个方法产生的,都有注解说明。
接下来我们分别介绍下以下几个Bean: