This commit is contained in:
Jane
2023-12-22 10:59:10 +08:00
parent 751c43e199
commit d1ede2d4aa
2774 changed files with 291509 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
package cn.datax.common.security.annotation;
import java.lang.annotation.*;
/**
* 服务调用不鉴权注解
*
* @author AllDataDC
* @date 2023/01/30
*/
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataInner {
/**
* 是否AOP统一处理
*
* @return false, true
*/
boolean value() default true;
}

View File

@@ -0,0 +1,26 @@
package cn.datax.common.security.config;
import cn.datax.common.security.annotation.DataInner;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
/**
* 服务间接口不鉴权处理逻辑
*
* @author AllDataDC
* @date 2023/01/30
*/
@Slf4j
@Aspect
public class DataSecurityInnerAspect {
@SneakyThrows
@Around("@annotation(dataInner)")
public Object around(ProceedingJoinPoint point, DataInner dataInner) {
log.info("feign内部接口访问 {} 不鉴权处理", point.getSignature().getName());
return point.proceed();
}
}

View File

@@ -0,0 +1,21 @@
package cn.datax.common.security.config;
import cn.datax.common.security.interceptor.DataServerProtectInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
public class DataSecurityInteceptorConfig implements WebMvcConfigurer {
@Bean
public HandlerInterceptor dataServerProtectInterceptor() {
return new DataServerProtectInterceptor();
}
@Override
@SuppressWarnings("all")
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(dataServerProtectInterceptor());
}
}

View File

@@ -0,0 +1,63 @@
package cn.datax.common.security.config;
import cn.datax.common.core.DataConstant;
import cn.datax.common.security.handler.DataAccessDeniedHandler;
import cn.datax.common.security.handler.DataAuthExceptionEntryPoint;
import feign.RequestInterceptor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import org.springframework.util.Base64Utils;
public class DataSecurityProtectConfig {
@Bean
@ConditionalOnMissingBean(name = "accessDeniedHandler")
public DataAccessDeniedHandler accessDeniedHandler() {
return new DataAccessDeniedHandler();
}
@Bean
@ConditionalOnMissingBean(name = "authenticationEntryPoint")
public DataAuthExceptionEntryPoint authenticationEntryPoint() {
return new DataAuthExceptionEntryPoint();
}
@Bean
@ConditionalOnMissingBean(value = PasswordEncoder.class)
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public DataSecurityInnerAspect dataSecurityInnerAspect() {
return new DataSecurityInnerAspect();
}
@Bean
public DataSecurityInteceptorConfig dataSecurityInteceptorConfig() {
return new DataSecurityInteceptorConfig();
}
@Bean
public RequestInterceptor oauth2FeignRequestInterceptor() {
return requestTemplate -> {
// 请求头中添加 Gateway Token
String gatewayToken = new String(Base64Utils.encode(DataConstant.Security.TOKENVALUE.getVal().getBytes()));
requestTemplate.header(DataConstant.Security.TOKENHEADER.getVal(), gatewayToken);
// 请求头中添加原请求头中的 Token
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null) {
Object details = authentication.getDetails();
if (details instanceof OAuth2AuthenticationDetails) {
String authorizationToken = ((OAuth2AuthenticationDetails) details).getTokenValue();
requestTemplate.header(DataConstant.Security.AUTHORIZATION.getVal(), DataConstant.Security.TOKENTYPE.getVal() + authorizationToken);
}
}
};
}
}

View File

@@ -0,0 +1,23 @@
package cn.datax.common.security.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.util.Collections;
@Configuration
public class MessageConverterConfig {
@Bean
public MappingJackson2HttpMessageConverter customMappingJackson2HttpMessageConverter() {
return new CustomMappingJackson2HttpMessageConverter();
}
static class CustomMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
public CustomMappingJackson2HttpMessageConverter() {
setSupportedMediaTypes(Collections.singletonList(MediaType.TEXT_PLAIN));
}
}
}

View File

@@ -0,0 +1,31 @@
package cn.datax.common.security.feign;
import feign.Feign;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.context.annotation.Bean;
import java.util.concurrent.TimeUnit;
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class FeignOkHttpConfig {
@Bean
public OkHttpClient okHttpClient() {
return new OkHttpClient.Builder()
// 连接超时
.connectTimeout(60, TimeUnit.SECONDS)
// 读超时
.readTimeout(60, TimeUnit.SECONDS)
// 写超时
.writeTimeout(60, TimeUnit.SECONDS)
// 是否自动重连
.retryOnConnectionFailure(true)
.connectionPool(new ConnectionPool())
.build();
}
}

View File

@@ -0,0 +1,21 @@
package cn.datax.common.security.handler;
import cn.datax.common.core.R;
import cn.datax.common.utils.ResponseUtil;
import org.springframework.http.MediaType;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class DataAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
ResponseUtil.makeResponse(
response, MediaType.APPLICATION_JSON_VALUE,
HttpServletResponse.SC_FORBIDDEN, R.error(HttpServletResponse.SC_FORBIDDEN, "没有权限访问该资源"));
}
}

View File

@@ -0,0 +1,21 @@
package cn.datax.common.security.handler;
import cn.datax.common.core.R;
import cn.datax.common.utils.ResponseUtil;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class DataAuthExceptionEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
ResponseUtil.makeResponse(
response, MediaType.APPLICATION_JSON_VALUE,
HttpServletResponse.SC_UNAUTHORIZED, R.error(HttpServletResponse.SC_UNAUTHORIZED, "无效的Token"));
}
}

View File

@@ -0,0 +1,32 @@
package cn.datax.common.security.interceptor;
import cn.datax.common.core.DataConstant;
import cn.datax.common.core.R;
import cn.datax.common.utils.ResponseUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.http.MediaType;
import org.springframework.util.Base64Utils;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class DataServerProtectInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
// 从请求头中获取Token
String token = request.getHeader(DataConstant.Security.TOKENHEADER.getVal());
String gatewayToken = new String(Base64Utils.encode(DataConstant.Security.TOKENVALUE.getVal().getBytes()));
// 校验Token的正确性
if (StrUtil.equals(gatewayToken, token)) {
return true;
} else {
ResponseUtil.makeResponse(
response, MediaType.APPLICATION_JSON_VALUE,
HttpServletResponse.SC_FORBIDDEN, R.error("请通过网关获取资源"));
return false;
}
}
}

View File

@@ -0,0 +1,60 @@
package cn.datax.common.security.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* 在线用户
* @author AllDataDC
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OnlineUserDto {
/**
* 用户名
*/
private String userName;
/**
* 昵称
*/
private String nickName;
/**
* 岗位
*/
private String dept;
/**
* 浏览器
*/
private String browser;
/**
* IP
*/
private String ip;
/**
* 地址
*/
private String address;
/**
* token
*/
private String key;
/**
* 登录时间
*/
private Date loginTime;
}

View File

@@ -0,0 +1,43 @@
package cn.datax.common.security.utils;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.*;
import java.util.Map;
@Slf4j
public class DataRedisTokenServices implements ResourceServerTokenServices {
@Setter
private TokenStore tokenStore;
@Override
public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException, InvalidTokenException {
OAuth2Authentication authentication = tokenStore.readAuthentication(accessToken);
OAuth2AccessToken token = readAccessToken(accessToken);
if(null == authentication || null == token){
throw new InvalidTokenException(accessToken);
}
DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter();
UserAuthenticationConverter userTokenConverter = new DataUserAuthenticationConverter();
accessTokenConverter.setUserTokenConverter(userTokenConverter);
Map<String, ?> map = accessTokenConverter.convertAccessToken(token, authentication);
if (map.containsKey("error")) {
if (this.log.isDebugEnabled()) {
this.log.debug("check_token returned error: " + map.get("error"));
}
throw new InvalidTokenException(accessToken);
} else {
return accessTokenConverter.extractAuthentication(map);
}
}
@Override
public OAuth2AccessToken readAccessToken(String accessToken) {
return tokenStore.readAccessToken(accessToken);
}
}

View File

@@ -0,0 +1,91 @@
package cn.datax.common.security.utils;
import cn.datax.common.core.DataConstant;
import cn.datax.common.core.DataRole;
import cn.datax.common.core.DataUser;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.provider.token.UserAuthenticationConverter;
import org.springframework.util.StringUtils;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* 根据checktoken的结果转化用户信息
*
* @author AllDataDC
* @date 2023/01/30
*/
public class DataUserAuthenticationConverter implements UserAuthenticationConverter {
private static final String N_A = "N/A";
private Collection<? extends GrantedAuthority> defaultAuthorities;
public void setDefaultAuthorities(String[] defaultAuthorities) {
this.defaultAuthorities = AuthorityUtils.commaSeparatedStringToAuthorityList(StringUtils.arrayToCommaDelimitedString(defaultAuthorities));
}
@Override
public Map<String, ?> convertUserAuthentication(Authentication authentication) {
Map<String, Object> response = new LinkedHashMap();
response.put(USERNAME, authentication.getName());
if (authentication.getAuthorities() != null && !authentication.getAuthorities().isEmpty()) {
response.put(AUTHORITIES, AuthorityUtils.authorityListToSet(authentication.getAuthorities()));
}
return response;
}
@Override
public Authentication extractAuthentication(Map<String, ?> map) {
if (map.containsKey(USERNAME)) {
Object principal = map.get(USERNAME);
Collection<? extends GrantedAuthority> authorities = this.getAuthorities(map);
String id = (String) map.get(DataConstant.UserAdditionalInfo.USERID.getKey());
String username = (String) map.get(DataConstant.UserAdditionalInfo.USERNAME.getKey());
String nickname = (String) map.get(DataConstant.UserAdditionalInfo.NICKNAME.getKey());
String dept = (String) map.get(DataConstant.UserAdditionalInfo.DEPT.getKey());
List<DataRole> roles = (List<DataRole>) map.get(DataConstant.UserAdditionalInfo.ROLE.getKey());
List<String> posts = (List<String>) map.get(DataConstant.UserAdditionalInfo.POST.getKey());
DataUser user = new DataUser(id, nickname, username, N_A, true
, true, true, true, authorities);
if (StrUtil.isNotBlank(dept)){
user.setDept(dept);
}
if (CollUtil.isNotEmpty(roles)){
user.setRoles(roles);
}
if (CollUtil.isNotEmpty(posts)){
user.setPosts(posts);
}
return new UsernamePasswordAuthenticationToken(user, N_A, authorities);
} else {
return null;
}
}
private Collection<? extends GrantedAuthority> getAuthorities(Map<String, ?> map) {
if (!map.containsKey(AUTHORITIES)) {
return this.defaultAuthorities;
} else {
Object authorities = map.get(AUTHORITIES);
if (authorities instanceof String) {
return AuthorityUtils.commaSeparatedStringToAuthorityList((String)authorities);
} else if (authorities instanceof Collection) {
return AuthorityUtils.commaSeparatedStringToAuthorityList(StringUtils.collectionToCommaDelimitedString((Collection)authorities));
} else {
throw new IllegalArgumentException("Authorities must be either a String or a Collection");
}
}
}
}

View File

@@ -0,0 +1,382 @@
package cn.datax.common.security.utils;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.AuthenticationKeyGenerator;
import org.springframework.security.oauth2.provider.token.DefaultAuthenticationKeyGenerator;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.JdkSerializationStrategy;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStoreSerializationStrategy;
import java.util.*;
public class RedisTokenStore implements TokenStore {
private static final String ACCESS = "access:";
private static final String AUTH_TO_ACCESS = "auth_to_access:";
private static final String AUTH = "online-token-";
private static final String REFRESH_AUTH = "refresh_auth:";
private static final String ACCESS_TO_REFRESH = "access_to_refresh:";
private static final String REFRESH = "refresh:";
private static final String REFRESH_TO_ACCESS = "refresh_to_access:";
private static final String CLIENT_ID_TO_ACCESS = "client_id_to_access:";
private static final String UNAME_TO_ACCESS = "uname_to_access:";
private final RedisConnectionFactory connectionFactory;
private AuthenticationKeyGenerator authenticationKeyGenerator = new DefaultAuthenticationKeyGenerator();
private RedisTokenStoreSerializationStrategy serializationStrategy = new JdkSerializationStrategy();
private String prefix = "";
public RedisTokenStore(RedisConnectionFactory connectionFactory) {
this.connectionFactory = connectionFactory;
}
public void setAuthenticationKeyGenerator(AuthenticationKeyGenerator authenticationKeyGenerator) {
this.authenticationKeyGenerator = authenticationKeyGenerator;
}
public void setSerializationStrategy(RedisTokenStoreSerializationStrategy serializationStrategy) {
this.serializationStrategy = serializationStrategy;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
private RedisConnection getConnection() {
return this.connectionFactory.getConnection();
}
private byte[] serialize(Object object) {
return this.serializationStrategy.serialize(object);
}
private byte[] serializeKey(String object) {
return this.serialize(this.prefix + object);
}
private OAuth2AccessToken deserializeAccessToken(byte[] bytes) {
return (OAuth2AccessToken)this.serializationStrategy.deserialize(bytes, OAuth2AccessToken.class);
}
private OAuth2Authentication deserializeAuthentication(byte[] bytes) {
return (OAuth2Authentication)this.serializationStrategy.deserialize(bytes, OAuth2Authentication.class);
}
private OAuth2RefreshToken deserializeRefreshToken(byte[] bytes) {
return (OAuth2RefreshToken)this.serializationStrategy.deserialize(bytes, OAuth2RefreshToken.class);
}
private byte[] serialize(String string) {
return this.serializationStrategy.serialize(string);
}
private String deserializeString(byte[] bytes) {
return this.serializationStrategy.deserializeString(bytes);
}
@Override
public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) {
String key = this.authenticationKeyGenerator.extractKey(authentication);
byte[] serializedKey = this.serializeKey(AUTH_TO_ACCESS + key);
byte[] bytes = null;
RedisConnection conn = this.getConnection();
try {
bytes = conn.get(serializedKey);
} finally {
conn.close();
}
OAuth2AccessToken accessToken = this.deserializeAccessToken(bytes);
if (accessToken != null) {
OAuth2Authentication storedAuthentication = this.readAuthentication(accessToken.getValue());
if (storedAuthentication == null || !key.equals(this.authenticationKeyGenerator.extractKey(storedAuthentication))) {
this.storeAccessToken(accessToken, authentication);
}
}
return accessToken;
}
@Override
public OAuth2Authentication readAuthentication(OAuth2AccessToken token) {
return this.readAuthentication(token.getValue());
}
@Override
public OAuth2Authentication readAuthentication(String token) {
byte[] bytes = null;
RedisConnection conn = this.getConnection();
try {
bytes = conn.get(this.serializeKey("online-token-" + token));
} finally {
conn.close();
}
OAuth2Authentication auth = this.deserializeAuthentication(bytes);
return auth;
}
@Override
public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) {
return this.readAuthenticationForRefreshToken(token.getValue());
}
public OAuth2Authentication readAuthenticationForRefreshToken(String token) {
RedisConnection conn = getConnection();
try {
byte[] bytes = conn.get(serializeKey(REFRESH_AUTH + token));
OAuth2Authentication auth = deserializeAuthentication(bytes);
return auth;
} finally {
conn.close();
}
}
@Override
public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
byte[] serializedAccessToken = serialize(token);
byte[] serializedAuth = serialize(authentication);
byte[] accessKey = serializeKey(ACCESS + token.getValue());
byte[] authKey = serializeKey(AUTH + token.getValue());
byte[] authToAccessKey = serializeKey(AUTH_TO_ACCESS + authenticationKeyGenerator.extractKey(authentication));
byte[] approvalKey = serializeKey(UNAME_TO_ACCESS + getApprovalKey(authentication));
byte[] clientId = serializeKey(CLIENT_ID_TO_ACCESS + authentication.getOAuth2Request().getClientId());
RedisConnection conn = getConnection();
try {
conn.openPipeline();
conn.stringCommands().set(accessKey, serializedAccessToken);
conn.stringCommands().set(authKey, serializedAuth);
conn.stringCommands().set(authToAccessKey, serializedAccessToken);
if (!authentication.isClientOnly()) {
conn.rPush(approvalKey, serializedAccessToken);
}
conn.rPush(clientId, serializedAccessToken);
if (token.getExpiration() != null) {
int seconds = token.getExpiresIn();
conn.expire(accessKey, seconds);
conn.expire(authKey, seconds);
conn.expire(authToAccessKey, seconds);
conn.expire(clientId, seconds);
conn.expire(approvalKey, seconds);
}
OAuth2RefreshToken refreshToken = token.getRefreshToken();
if (refreshToken != null && refreshToken.getValue() != null) {
byte[] refresh = serialize(token.getRefreshToken().getValue());
byte[] auth = serialize(token.getValue());
byte[] refreshToAccessKey = serializeKey(REFRESH_TO_ACCESS + token.getRefreshToken().getValue());
conn.stringCommands().set(refreshToAccessKey, auth);
byte[] accessToRefreshKey = serializeKey(ACCESS_TO_REFRESH + token.getValue());
conn.stringCommands().set(accessToRefreshKey, refresh);
if (refreshToken instanceof ExpiringOAuth2RefreshToken) {
ExpiringOAuth2RefreshToken expiringRefreshToken = (ExpiringOAuth2RefreshToken) refreshToken;
Date expiration = expiringRefreshToken.getExpiration();
if (expiration != null) {
int seconds = Long.valueOf((expiration.getTime() - System.currentTimeMillis()) / 1000L)
.intValue();
conn.expire(refreshToAccessKey, seconds);
conn.expire(accessToRefreshKey, seconds);
}
}
}
conn.closePipeline();
} finally {
conn.close();
}
}
private static String getApprovalKey(OAuth2Authentication authentication) {
String userName = authentication.getUserAuthentication() == null ? "": authentication.getUserAuthentication().getName();
return getApprovalKey(authentication.getOAuth2Request().getClientId(), userName);
}
private static String getApprovalKey(String clientId, String userName) {
return clientId + (userName == null ? "" : ":" + userName);
}
@Override
public void removeAccessToken(OAuth2AccessToken accessToken) {
this.removeAccessToken(accessToken.getValue());
}
@Override
public OAuth2AccessToken readAccessToken(String tokenValue) {
byte[] key = serializeKey(ACCESS + tokenValue);
byte[] bytes = null;
RedisConnection conn = getConnection();
try {
bytes = conn.get(key);
} finally {
conn.close();
}
OAuth2AccessToken accessToken = deserializeAccessToken(bytes);
return accessToken;
}
public void removeAccessToken(String tokenValue) {
byte[] accessKey = serializeKey(ACCESS + tokenValue);
byte[] authKey = serializeKey(AUTH + tokenValue);
byte[] accessToRefreshKey = serializeKey(ACCESS_TO_REFRESH + tokenValue);
RedisConnection conn = getConnection();
try {
conn.openPipeline();
conn.get(accessKey);
conn.get(authKey);
conn.del(accessKey);
conn.del(accessToRefreshKey);
// Don't remove the refresh token - it's up to the caller to do that
conn.del(authKey);
List<Object> results = conn.closePipeline();
byte[] access = (byte[]) results.get(0);
byte[] auth = (byte[]) results.get(1);
OAuth2Authentication authentication = deserializeAuthentication(auth);
if (authentication != null) {
String key = authenticationKeyGenerator.extractKey(authentication);
byte[] authToAccessKey = serializeKey(AUTH_TO_ACCESS + key);
byte[] unameKey = serializeKey(UNAME_TO_ACCESS + getApprovalKey(authentication));
byte[] clientId = serializeKey(CLIENT_ID_TO_ACCESS + authentication.getOAuth2Request().getClientId());
conn.openPipeline();
conn.del(authToAccessKey);
conn.lRem(unameKey, 1, access);
conn.lRem(clientId, 1, access);
conn.del(serialize(ACCESS + key));
conn.closePipeline();
}
} finally {
conn.close();
}
}
@Override
public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) {
byte[] refreshKey = serializeKey(REFRESH + refreshToken.getValue());
byte[] refreshAuthKey = serializeKey(REFRESH_AUTH + refreshToken.getValue());
byte[] serializedRefreshToken = serialize(refreshToken);
RedisConnection conn = getConnection();
try {
conn.openPipeline();
conn.stringCommands().set(refreshKey, serializedRefreshToken);
conn.stringCommands().set(refreshAuthKey, serialize(authentication));
if (refreshToken instanceof ExpiringOAuth2RefreshToken) {
ExpiringOAuth2RefreshToken expiringRefreshToken = (ExpiringOAuth2RefreshToken) refreshToken;
Date expiration = expiringRefreshToken.getExpiration();
if (expiration != null) {
int seconds = Long.valueOf((expiration.getTime() - System.currentTimeMillis()) / 1000L)
.intValue();
conn.expire(refreshKey, seconds);
conn.expire(refreshAuthKey, seconds);
}
}
conn.closePipeline();
} finally {
conn.close();
}
}
@Override
public OAuth2RefreshToken readRefreshToken(String tokenValue) {
byte[] key = serializeKey(REFRESH + tokenValue);
byte[] bytes = null;
RedisConnection conn = getConnection();
try {
bytes = conn.get(key);
} finally {
conn.close();
}
OAuth2RefreshToken refreshToken = deserializeRefreshToken(bytes);
return refreshToken;
}
@Override
public void removeRefreshToken(OAuth2RefreshToken refreshToken) {
this.removeRefreshToken(refreshToken.getValue());
}
public void removeRefreshToken(String tokenValue) {
byte[] refreshKey = serializeKey(REFRESH + tokenValue);
byte[] refreshAuthKey = serializeKey(REFRESH_AUTH + tokenValue);
byte[] refresh2AccessKey = serializeKey(REFRESH_TO_ACCESS + tokenValue);
byte[] access2RefreshKey = serializeKey(ACCESS_TO_REFRESH + tokenValue);
RedisConnection conn = getConnection();
try {
conn.openPipeline();
conn.del(refreshKey);
conn.del(refreshAuthKey);
conn.del(refresh2AccessKey);
conn.del(access2RefreshKey);
conn.closePipeline();
} finally {
conn.close();
}
}
@Override
public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) {
this.removeAccessTokenUsingRefreshToken(refreshToken.getValue());
}
private void removeAccessTokenUsingRefreshToken(String refreshToken) {
byte[] key = serializeKey(REFRESH_TO_ACCESS + refreshToken);
List<Object> results = null;
RedisConnection conn = getConnection();
try {
conn.openPipeline();
conn.get(key);
conn.del(key);
results = conn.closePipeline();
} finally {
conn.close();
}
if (results == null) {
return;
}
byte[] bytes = (byte[]) results.get(0);
String accessToken = deserializeString(bytes);
if (accessToken != null) {
removeAccessToken(accessToken);
}
}
@Override
public Collection<OAuth2AccessToken> findTokensByClientIdAndUserName(String clientId, String userName) {
byte[] approvalKey = serializeKey(UNAME_TO_ACCESS + getApprovalKey(clientId, userName));
List<byte[]> byteList = null;
RedisConnection conn = getConnection();
try {
byteList = conn.lRange(approvalKey, 0, -1);
} finally {
conn.close();
}
if (byteList == null || byteList.size() == 0) {
return Collections.<OAuth2AccessToken> emptySet();
}
List<OAuth2AccessToken> accessTokens = new ArrayList<OAuth2AccessToken>(byteList.size());
for (byte[] bytes : byteList) {
OAuth2AccessToken accessToken = deserializeAccessToken(bytes);
accessTokens.add(accessToken);
}
return Collections.<OAuth2AccessToken> unmodifiableCollection(accessTokens);
}
@Override
public Collection<OAuth2AccessToken> findTokensByClientId(String clientId) {
byte[] key = serializeKey(CLIENT_ID_TO_ACCESS + clientId);
List<byte[]> byteList = null;
RedisConnection conn = getConnection();
try {
byteList = conn.lRange(key, 0, -1);
} finally {
conn.close();
}
if (byteList == null || byteList.size() == 0) {
return Collections.<OAuth2AccessToken> emptySet();
}
List<OAuth2AccessToken> accessTokens = new ArrayList<OAuth2AccessToken>(byteList.size());
for (byte[] bytes : byteList) {
OAuth2AccessToken accessToken = deserializeAccessToken(bytes);
accessTokens.add(accessToken);
}
return Collections.<OAuth2AccessToken> unmodifiableCollection(accessTokens);
}
}

View File

@@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.datax.common.security.feign.FeignOkHttpConfig