Browse Source

采用更简洁的TokenGranter拓展方案

test v2.4.0.release
smallchill 5 years ago
parent
commit
1878de3be2
  1. 28
      blade-auth/src/main/java/org/springblade/auth/config/BladeAuthorizationServerConfiguration.java
  2. 66
      blade-auth/src/main/java/org/springblade/auth/config/BladeTokenGranterConfiguration.java
  3. 133
      blade-auth/src/main/java/org/springblade/auth/granter/BladeTokenGranter.java

28
blade-auth/src/main/java/org/springblade/auth/config/BladeAuthorizationServerConfiguration.java

@ -22,6 +22,7 @@ import org.springblade.auth.constant.AuthConstant;
import org.springblade.auth.granter.BladeTokenGranter;
import org.springblade.auth.props.AuthProperties;
import org.springblade.auth.service.BladeClientDetailsServiceImpl;
import org.springblade.core.redis.cache.BladeRedisCache;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
@ -32,9 +33,15 @@ import org.springframework.security.oauth2.config.annotation.web.configuration.A
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.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.TokenGranter;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;
/**
* 认证服务器配置
@ -56,14 +63,33 @@ public class BladeAuthorizationServerConfiguration extends AuthorizationServerCo
private TokenStore tokenStore;
private BladeTokenGranter tokenGranter;
private TokenEnhancer jwtTokenEnhancer;
private JwtAccessTokenConverter jwtAccessTokenConverter;
private BladeRedisCache redisCache;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
//获取自定义tokenGranter
TokenGranter tokenGranter = BladeTokenGranter.getTokenGranter(authenticationManager, endpoints, redisCache);
//配置端点
endpoints.tokenStore(tokenStore)
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService)
.tokenGranter(tokenGranter);
//扩展token返回结果
if (jwtAccessTokenConverter != null && jwtTokenEnhancer != null) {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
List<TokenEnhancer> enhancerList = new ArrayList<>();
enhancerList.add(jwtTokenEnhancer);
enhancerList.add(jwtAccessTokenConverter);
tokenEnhancerChain.setTokenEnhancers(enhancerList);
//jwt增强
endpoints.tokenEnhancer(tokenEnhancerChain).accessTokenConverter(jwtAccessTokenConverter);
}
}
/**

66
blade-auth/src/main/java/org/springblade/auth/config/BladeTokenGranterConfiguration.java

@ -1,66 +0,0 @@
/*
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the dreamlu.net developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: Chill 庄骞 (smallchill@163.com)
*/
package org.springblade.auth.config;
import lombok.AllArgsConstructor;
import org.springblade.auth.granter.BladeTokenGranter;
import org.springblade.auth.props.AuthProperties;
import org.springblade.core.redis.cache.BladeRedisCache;
import org.springblade.system.user.feign.IUserClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import javax.sql.DataSource;
/**
* 自定义TokenGranter配置类
*
* @author Chill
*/
@Configuration
@AllArgsConstructor
public class BladeTokenGranterConfiguration {
private final DataSource dataSource;
private AuthenticationManager authenticationManager;
private UserDetailsService userDetailsService;
private TokenStore tokenStore;
private TokenEnhancer jwtTokenEnhancer;
private JwtAccessTokenConverter jwtAccessTokenConverter;
private AuthProperties authProperties;
private IUserClient userClient;
private BladeRedisCache redisCache;
@Bean
public BladeTokenGranter bladeTokenGranter() {
return new BladeTokenGranter(dataSource, authenticationManager, userDetailsService, tokenStore, jwtTokenEnhancer, jwtAccessTokenConverter, authProperties, userClient, redisCache);
}
}

133
blade-auth/src/main/java/org/springblade/auth/granter/BladeTokenGranter.java

@ -16,30 +16,12 @@
*/
package org.springblade.auth.granter;
import org.springblade.auth.constant.AuthConstant;
import org.springblade.auth.props.AuthProperties;
import org.springblade.auth.service.BladeClientDetailsServiceImpl;
import org.springblade.core.redis.cache.BladeRedisCache;
import org.springblade.system.user.feign.IUserClient;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.client.ClientCredentialsTokenGranter;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeTokenGranter;
import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.implicit.ImplicitTokenGranter;
import org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter;
import org.springframework.security.oauth2.provider.refresh.RefreshTokenGranter;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.*;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.CompositeTokenGranter;
import org.springframework.security.oauth2.provider.TokenGranter;
import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -49,109 +31,18 @@ import java.util.List;
*
* @author Chill
*/
public class BladeTokenGranter implements TokenGranter {
private final DataSource dataSource;
private AuthenticationManager authenticationManager;
private UserDetailsService userDetailsService;
private TokenStore tokenStore;
private TokenEnhancer jwtTokenEnhancer;
private JwtAccessTokenConverter jwtAccessTokenConverter;
private CompositeTokenGranter delegate;
private AuthProperties authProperties;
private IUserClient userClient;
private BladeRedisCache redisCache;
public BladeTokenGranter(DataSource dataSource, AuthenticationManager authenticationManager, UserDetailsService userDetailsService, TokenStore tokenStore, TokenEnhancer jwtTokenEnhancer, JwtAccessTokenConverter jwtAccessTokenConverter, AuthProperties authProperties, IUserClient userClient, BladeRedisCache redisCache) {
this.dataSource = dataSource;
this.authenticationManager = authenticationManager;
this.userDetailsService = userDetailsService;
this.tokenStore = tokenStore;
this.jwtTokenEnhancer = jwtTokenEnhancer;
this.jwtAccessTokenConverter = jwtAccessTokenConverter;
this.userClient = userClient;
this.authProperties = authProperties;
this.redisCache = redisCache;
}
@Override
public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) {
if (delegate == null) {
delegate = new CompositeTokenGranter(getDefaultTokenGranters());
}
return delegate.grant(grantType, tokenRequest);
}
public class BladeTokenGranter {
/**
* 自定义授权模式
* 自定义tokenGranter
*/
private List<TokenGranter> getDefaultTokenGranters() {
ClientDetailsService clientDetails = clientDetailsService();
AuthorizationServerTokenServices tokenServices = tokenServices();
AuthorizationCodeServices authorizationCodeServices = authorizationCodeServices();
OAuth2RequestFactory requestFactory = requestFactory();
List<TokenGranter> tokenGranters = new ArrayList<>();
tokenGranters.add(new AuthorizationCodeTokenGranter(tokenServices, authorizationCodeServices, clientDetails, requestFactory));
tokenGranters.add(new RefreshTokenGranter(tokenServices, clientDetails, requestFactory));
ImplicitTokenGranter implicit = new ImplicitTokenGranter(tokenServices, clientDetails, requestFactory);
tokenGranters.add(implicit);
tokenGranters.add(new ClientCredentialsTokenGranter(tokenServices, clientDetails, requestFactory));
if (authenticationManager != null) {
tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager, tokenServices, clientDetails, requestFactory));
}
// 自定义Granter
tokenGranters.add(new CaptchaTokenGranter(authenticationManager, tokenServices, clientDetails, requestFactory, redisCache));
return tokenGranters;
}
private ClientDetailsService clientDetailsService() {
BladeClientDetailsServiceImpl clientDetailsService = new BladeClientDetailsServiceImpl(dataSource);
clientDetailsService.setSelectClientDetailsSql(AuthConstant.DEFAULT_SELECT_STATEMENT);
clientDetailsService.setFindClientDetailsSql(AuthConstant.DEFAULT_FIND_STATEMENT);
return clientDetailsService;
}
private AuthorizationCodeServices authorizationCodeServices() {
return new InMemoryAuthorizationCodeServices();
}
private OAuth2RequestFactory requestFactory() {
return new DefaultOAuth2RequestFactory(clientDetailsService());
}
private DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore);
defaultTokenServices.setSupportRefreshToken(true);
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
List<TokenEnhancer> enhancerList = new ArrayList<>();
enhancerList.add(jwtTokenEnhancer);
enhancerList.add(jwtAccessTokenConverter);
tokenEnhancerChain.setTokenEnhancers(enhancerList);
defaultTokenServices.setTokenEnhancer(tokenEnhancerChain);
defaultTokenServices.setClientDetailsService(clientDetailsService());
addUserDetailsService(defaultTokenServices, userDetailsService);
return defaultTokenServices;
}
private void addUserDetailsService(DefaultTokenServices tokenServices, UserDetailsService userDetailsService) {
if (userDetailsService != null) {
PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
provider.setPreAuthenticatedUserDetailsService(new UserDetailsByNameServiceWrapper<>(userDetailsService));
tokenServices.setAuthenticationManager(new ProviderManager(Collections.singletonList(provider)));
}
public static TokenGranter getTokenGranter(final AuthenticationManager authenticationManager, final AuthorizationServerEndpointsConfigurer endpoints, BladeRedisCache redisCache) {
// 默认tokenGranter集合
List<TokenGranter> granters = new ArrayList<>(Collections.singletonList(endpoints.getTokenGranter()));
// 增加验证码模式
granters.add(new CaptchaTokenGranter(authenticationManager, endpoints.getTokenServices(), endpoints.getClientDetailsService(), endpoints.getOAuth2RequestFactory(), redisCache));
// 组合tokenGranter集合
return new CompositeTokenGranter(granters);
}
}

Loading…
Cancel
Save