一、前言
距离之前写的有2年了,在工作中也实践了不少,之前引入的依赖变成了spring-security-oauth2-autoconfigure和spring-security-oauth2-jose,选取的还是比较新的版本springboot2.6.4 和springcloud2021.0.1
二、auth server
pom文件
4.0.0
com.wenx
auth-gateway
0.0.1-SNAPSHOT
com.wenx.oauth
au-oauth
0.0.1-SNAPSHOT
au-oauth
au-oauth
1.8
com.wenx
au-domain
0.0.1-SNAPSHOT
compile
org.springframework.boot
spring-boot-starter-aop
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-redis
org.springframework.security.oauth.boot
spring-security-oauth2-autoconfigure
org.springframework.security
spring-security-oauth2-jose
cn.hutool
hutool-all
5.4.3
com.alibaba
fastjson
1.2.73
com.google.guava
guava
31.0.1-jre
commons-beanutils
commons-beanutils
1.9.4
org.springframework.data
spring-data-redis
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
cn.hutool
hutool-all
5.4.3
compile
org.apache.commons
commons-lang3
auth config
@Slf4j
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Resource
private DataSource dataSource;
/**
* 注入authenticationManager
* 来支持 password grant type
*/
@Resource
private AuthenticationManager authenticationManager;
@Resource
private LettuceConnectionFactory lettuceConnectionFactory;
@Resource
private AuUserDetailsService userDetailsService;
@PostConstruct
public void postConstruct() {
log.debug("[Authorization Server in component oauth] Auto Configure.");
}
/**
* 配置客户端详情服务(ClientDetailsService)
* 客户端详情信息在这里进行初始化
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(jdbcClientDetailsService());
}
/**
* 配置令牌端点(Token Endpoint)的安全约束
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
.tokenKeyAccess("isAuthenticated()")
.checkTokenAccess("isAuthenticated()")
.allowFormAuthenticationForClients();
}
/**
* config
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.authenticationManager(authenticationManager)
// 授权允许存储方式
.approvalStore(createApprovalStore())
// 授权码模式code存储方式
.authorizationCodeServices(createAuthorizationCodeServices())
// token存储方式
.tokenStore(createTokenStore())
.userDetailsService(userDetailsService)
.accessTokenConverter(defaultAccessTokenConverter());
// 自定义确认授权页面
endpoints.pathMapping("/oauth/confirm_access", "/oauth/confirm_access");
// 自定义错误页
endpoints.pathMapping("/oauth/error", "/oauth/error");
}
/**
* 声明 TokenStore 管理方式实现
*
* @return TokenStore
*/
@Bean
public TokenStore createTokenStore() {
return new RedisTokenStore(lettuceConnectionFactory);
}
/**
* 授权store。主要用于Authorization Code模式中,确认授权范围页面。
*
* @return ApprovalStore
*/
@Bean
public ApprovalStore createApprovalStore() {
TokenApprovalStore tokenApprovalStore = new TokenApprovalStore();
tokenApprovalStore.setTokenStore(createTokenStore());
return tokenApprovalStore;
}
/**
* 授权码
*
* @return AuthorizationCodeServices
*/
@Bean
public AuthorizationCodeServices createAuthorizationCodeServices() {
return new JdbcAuthorizationCodeServices(dataSource);
}
/**
* ClientDetails
* @return
*/
@Bean
public ClientDetailsService jdbcClientDetailsService(){
return new JdbcClientDetailsService(dataSource);
}
@Bean
public DefaultAccessTokenConverter defaultAccessTokenConverter(){
return new DefaultAccessTokenConverter();
}
}
web config
@Configuration
@EnableWebSecurity
@Order(2)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final Logger log = LoggerFactory.getLogger(WebSecurityConfiguration.class);
@Autowired
private DataSource dataSource;
/**
* {@link AuthorizationServerEndpointsConfiguration#defaultAuthorizationServerTokenServices()}
*/
@PostConstruct
public void postConstruct() {
log.debug("|- Core [Web Security Configurer Adapter] Auto Configure.");
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
jdbcTokenRepository.setDataSource(dataSource);
return jdbcTokenRepository;
}
/**
* 大体意思就是antMatcher()``是HttpSecurity的一个方法,他只告诉了Spring我只配置了一个我这个Adapter能处理哪个的url,它与authorizeRequests()没有任何关系。
*
* 然后使用authorizeRequests().antMatchers()是告诉你在antMatchers()中指定的一个或多个路径,比如执行permitAll()或hasRole()。他们在第一个http.antMatcher()匹配时就会生效。
*
* @param http
* @throws Exception
*/
@Override
public void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
// 禁用CSRF 开启跨域
http.csrf().disable().cors();
http.requestMatchers().antMatchers("/oauth/**", "/login**", "/open/**")
.and()
.authorizeRequests()
.antMatchers("/oauth/**").authenticated()
.antMatchers("/open/**").permitAll()
.antMatchers("/actuator/**").permitAll()
.anyRequest().authenticated()
.and().logout().permitAll();
}
}
三、resource server
pom
4.0.0
com.wenx
auth-gateway
0.0.1-SNAPSHOT
com.wenx
auth-user
0.0.1-SNAPSHOT
auth-user
auth-user
1.8
com.wenx
au-domain
0.0.1-SNAPSHOT
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-configuration-processor
true
org.springframework.boot
spring-boot-starter-aop
org.springframework.security.oauth.boot
spring-security-oauth2-autoconfigure
org.springframework.security
spring-security-oauth2-jose
mysql
mysql-connector-java
runtime
cn.hutool
hutool-all
5.4.3
com.alibaba
fastjson
1.2.73
com.baomidou
mybatis-plus-boot-starter
3.4.1
org.apache.commons
commons-lang3
3.9
javax.servlet
javax.servlet-api
4.0.1
provided
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
resource config
@Configuration
@EnableResourceServer
@Slf4j
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Value("${security.oauth2.client.client-id}")
private String clientId;
@Value("${security.oauth2.resource.id}")
private String resourceId;
@Value("${security.oauth2.client.client-secret}")
private String secret;
@Value("${security.oauth2.resource.token-info-uri}")
private String checkTokenEndpointUrl;
@PostConstruct
public void postConstruct() {
log.debug(" |- Core [Herodotus Resource Server in component oauth] Auto Configure.");
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
// 认证鉴权错误处理,为了统一异常处理。每个资源服务器都应该加上。
resources.resourceId(resourceId).stateless(true);
resources.tokenServices(tokenService());
super.configure(resources);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
// 禁用CSRF 开启跨域
http.csrf().disable().cors();
// @formatter:off
http.authorizeRequests()
.antMatchers("/api/hello").permitAll()
// 指定监控访问权限
.requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
.anyRequest().authenticated();
// 防止iframe 造成跨域
http.headers().frameOptions().disable();
}
@Bean
public RemoteTokenServices tokenService() {
RemoteTokenServices tokenService = new RemoteTokenServices();
tokenService.setClientId(clientId);
tokenService.setClientSecret(secret);
tokenService.setCheckTokenEndpointUrl(checkTokenEndpointUrl);
return tokenService;
}
}
写法的话没太多变化,拓展内容就不写了,demo地址是 https://github.com/wenxpro/auth-gateway
参考项目:https://gitee.com/herodotus/eurynome-cloud
-end-