优化代码
This commit is contained in:
parent
46a1b2094d
commit
295cedcaed
@ -0,0 +1,54 @@
|
|||||||
|
package cn.zyjblogs.config.security;
|
||||||
|
|
||||||
|
import cn.zyjblogs.starter.common.entity.constant.CommonRedisKeyConstant;
|
||||||
|
import cn.zyjblogs.starter.common.entity.context.BaseContext;
|
||||||
|
import cn.zyjblogs.starter.redis.utils.RedisTemplateHandler;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.security.web.csrf.CsrfToken;
|
||||||
|
import org.springframework.security.web.csrf.CsrfTokenRepository;
|
||||||
|
import org.springframework.security.web.csrf.DefaultCsrfToken;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class OauthCsrfTokenRepository implements CsrfTokenRepository {
|
||||||
|
static final String DEFAULT_CSRF_COOKIE_NAME = "XSRF-TOKEN";
|
||||||
|
static final String DEFAULT_CSRF_PARAMETER_NAME = "_csrf";
|
||||||
|
static final String DEFAULT_CSRF_HEADER_NAME = "X-XSRF-TOKEN";
|
||||||
|
private String parameterName = "_csrf";
|
||||||
|
private String headerName = "X-XSRF-TOKEN";
|
||||||
|
|
||||||
|
private final RedisTemplateHandler<String, String> redisTemplateHandler;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CsrfToken generateToken(HttpServletRequest httpServletRequest) {
|
||||||
|
return new DefaultCsrfToken(this.headerName, this.parameterName, this.createNewToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveToken(CsrfToken csrfToken, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
|
||||||
|
String tokenValue = csrfToken == null ? "" : csrfToken.getToken();
|
||||||
|
String key = CommonRedisKeyConstant.XSRF_TOKEN + BaseContext.getUsername();
|
||||||
|
redisTemplateHandler.set(key, tokenValue);
|
||||||
|
redisTemplateHandler.expire(key, 30, TimeUnit.DAYS);
|
||||||
|
httpServletResponse.setHeader(headerName, tokenValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CsrfToken loadToken(HttpServletRequest httpServletRequest) {
|
||||||
|
String tokenValue = redisTemplateHandler.get(CommonRedisKeyConstant.XSRF_TOKEN + BaseContext.getUsername());
|
||||||
|
if (tokenValue == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new DefaultCsrfToken(this.headerName, this.parameterName, tokenValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createNewToken() {
|
||||||
|
return UUID.randomUUID().toString();
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,7 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
|
|||||||
private String resourceId;
|
private String resourceId;
|
||||||
private final TokenStore tokenStore;
|
private final TokenStore tokenStore;
|
||||||
private final WhiteListProperties whiteListProperties;
|
private final WhiteListProperties whiteListProperties;
|
||||||
|
// private final CsrfTokenRepository oauthCsrfTokenRepository;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
|
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
|
||||||
@ -47,9 +48,8 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void configure(HttpSecurity http) throws Exception {
|
public void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http.csrf().disable()
|
||||||
.csrf()
|
// .disable()
|
||||||
.disable()
|
|
||||||
//限制资源服务器作用范围为 "/user/**", "/demo/**"
|
//限制资源服务器作用范围为 "/user/**", "/demo/**"
|
||||||
.requestMatchers().antMatchers("/v*/**", "/demo/**",
|
.requestMatchers().antMatchers("/v*/**", "/demo/**",
|
||||||
String.join(",", whiteListProperties.getAllowPaths()))
|
String.join(",", whiteListProperties.getAllowPaths()))
|
||||||
|
@ -20,6 +20,7 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
|||||||
private final OauthUserDetailsServiceImpl userDetailsService;
|
private final OauthUserDetailsServiceImpl userDetailsService;
|
||||||
private final OauthAuthenticationProvider oauthAuthenticationProvider;
|
private final OauthAuthenticationProvider oauthAuthenticationProvider;
|
||||||
private final PasswordEncoder passwordEncoder;
|
private final PasswordEncoder passwordEncoder;
|
||||||
|
// private final CsrfTokenRepository oauthCsrfTokenRepository;
|
||||||
/**
|
/**
|
||||||
* 密码编码解码
|
* 密码编码解码
|
||||||
*
|
*
|
||||||
|
@ -8,6 +8,8 @@ import org.springframework.security.oauth2.common.util.RandomValueStringGenerato
|
|||||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||||
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
|
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author zhuyijun
|
* @author zhuyijun
|
||||||
*/
|
*/
|
||||||
@ -32,7 +34,9 @@ public class OauthAuthorizationCodeServices implements AuthorizationCodeServices
|
|||||||
@Override
|
@Override
|
||||||
public String createAuthorizationCode(OAuth2Authentication oAuth2Authentication) {
|
public String createAuthorizationCode(OAuth2Authentication oAuth2Authentication) {
|
||||||
String code = this.generator.generate();
|
String code = this.generator.generate();
|
||||||
redisTemplateHandler.hPut(CommonRedisKeyConstant.AUTHORIZATION_CODE, code, oAuth2Authentication);
|
redisTemplateHandler.set(CommonRedisKeyConstant.AUTHORIZATION_CODE + ":" + code, oAuth2Authentication);
|
||||||
|
redisTemplateHandler.expire(CommonRedisKeyConstant.AUTHORIZATION_CODE + ":" + code, 1, TimeUnit.MINUTES);
|
||||||
|
// redisTemplateHandler.hPut(CommonRedisKeyConstant.AUTHORIZATION_CODE, code, oAuth2Authentication);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,8 +48,10 @@ public class OauthAuthorizationCodeServices implements AuthorizationCodeServices
|
|||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@Override
|
@Override
|
||||||
public OAuth2Authentication consumeAuthorizationCode(String code) throws InvalidGrantException {
|
public OAuth2Authentication consumeAuthorizationCode(String code) throws InvalidGrantException {
|
||||||
OAuth2Authentication oAuth2Authentication = redisTemplateHandler.<String, OAuth2Authentication>hGet(CommonRedisKeyConstant.AUTHORIZATION_CODE, code);
|
// OAuth2Authentication oAuth2Authentication = redisTemplateHandler.<String, OAuth2Authentication>hGet(CommonRedisKeyConstant.AUTHORIZATION_CODE, code);
|
||||||
redisTemplateHandler.hDelete(CommonRedisKeyConstant.AUTHORIZATION_CODE, code);
|
// redisTemplateHandler.hDelete(CommonRedisKeyConstant.AUTHORIZATION_CODE, code);
|
||||||
|
OAuth2Authentication oAuth2Authentication = redisTemplateHandler.get(CommonRedisKeyConstant.AUTHORIZATION_CODE + ":" + code);
|
||||||
|
redisTemplateHandler.delete(CommonRedisKeyConstant.AUTHORIZATION_CODE + ":" + code);
|
||||||
return oAuth2Authentication;
|
return oAuth2Authentication;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,16 +5,10 @@ import cn.zyjblogs.server.client.po.OauthClientDetail;
|
|||||||
import cn.zyjblogs.starter.common.utils.bean.BeanUtils;
|
import cn.zyjblogs.starter.common.utils.bean.BeanUtils;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.security.oauth2.provider.ClientAlreadyExistsException;
|
import org.springframework.security.oauth2.provider.*;
|
||||||
import org.springframework.security.oauth2.provider.ClientDetails;
|
|
||||||
import org.springframework.security.oauth2.provider.ClientDetailsService;
|
|
||||||
import org.springframework.security.oauth2.provider.ClientRegistrationException;
|
|
||||||
import org.springframework.security.oauth2.provider.ClientRegistrationService;
|
|
||||||
import org.springframework.security.oauth2.provider.NoSuchClientException;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
@ -31,16 +25,16 @@ public class OauthClientDetailsServiceImpl implements ClientDetailsService, Clie
|
|||||||
private final PasswordEncoder passwordEncoder;
|
private final PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
|
public OauthClientDetail loadClientByClientId(String clientId) throws ClientRegistrationException {
|
||||||
LambdaQueryWrapper<OauthClientDetail> wrapper = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<OauthClientDetail> wrapper = Wrappers.lambdaQuery();
|
||||||
wrapper.eq(OauthClientDetail::getClientId,clientId);
|
wrapper.eq(OauthClientDetail::getClientId, clientId);
|
||||||
return oauthClientDetailsMapper.selectOne(wrapper);
|
return oauthClientDetailsMapper.selectOne(wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addClientDetails(ClientDetails clientDetails) throws ClientAlreadyExistsException {
|
public void addClientDetails(ClientDetails clientDetails) throws ClientAlreadyExistsException {
|
||||||
OauthClientDetail oauthClientDetail = new OauthClientDetail(clientDetails);
|
OauthClientDetail oauthClientDetail = new OauthClientDetail(clientDetails);
|
||||||
if (oauthClientDetail.getClientSecret() != null){
|
if (oauthClientDetail.getClientSecret() != null) {
|
||||||
oauthClientDetail.setClientSecret(passwordEncoder.encode(oauthClientDetail.getClientSecret()));
|
oauthClientDetail.setClientSecret(passwordEncoder.encode(oauthClientDetail.getClientSecret()));
|
||||||
}
|
}
|
||||||
oauthClientDetailsMapper.insert(oauthClientDetail);
|
oauthClientDetailsMapper.insert(oauthClientDetail);
|
||||||
@ -49,31 +43,31 @@ public class OauthClientDetailsServiceImpl implements ClientDetailsService, Clie
|
|||||||
@Override
|
@Override
|
||||||
public void updateClientDetails(ClientDetails clientDetails) throws NoSuchClientException {
|
public void updateClientDetails(ClientDetails clientDetails) throws NoSuchClientException {
|
||||||
LambdaUpdateWrapper<OauthClientDetail> updateWrapper = Wrappers.lambdaUpdate();
|
LambdaUpdateWrapper<OauthClientDetail> updateWrapper = Wrappers.lambdaUpdate();
|
||||||
updateWrapper.eq(OauthClientDetail::getClientId,clientDetails.getClientId());
|
updateWrapper.eq(OauthClientDetail::getClientId, clientDetails.getClientId());
|
||||||
OauthClientDetail oauthClientDetail = new OauthClientDetail(clientDetails);
|
OauthClientDetail oauthClientDetail = new OauthClientDetail(clientDetails);
|
||||||
oauthClientDetailsMapper.update(oauthClientDetail,updateWrapper);
|
oauthClientDetailsMapper.update(oauthClientDetail, updateWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateClientSecret(String clientId, String clientSecret) throws NoSuchClientException {
|
public void updateClientSecret(String clientId, String clientSecret) throws NoSuchClientException {
|
||||||
LambdaUpdateWrapper<OauthClientDetail> updateWrapper = Wrappers.lambdaUpdate();
|
LambdaUpdateWrapper<OauthClientDetail> updateWrapper = Wrappers.lambdaUpdate();
|
||||||
updateWrapper.eq(OauthClientDetail::getClientId,clientId).set(OauthClientDetail::getClientSecret,passwordEncoder.encode(clientSecret));
|
updateWrapper.eq(OauthClientDetail::getClientId, clientId).set(OauthClientDetail::getClientSecret, passwordEncoder.encode(clientSecret));
|
||||||
oauthClientDetailsMapper.update(null,updateWrapper);
|
oauthClientDetailsMapper.update(null, updateWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeClientDetails(String clientId) throws NoSuchClientException {
|
public void removeClientDetails(String clientId) throws NoSuchClientException {
|
||||||
LambdaUpdateWrapper<OauthClientDetail> updateWrapper = Wrappers.lambdaUpdate();
|
LambdaUpdateWrapper<OauthClientDetail> updateWrapper = Wrappers.lambdaUpdate();
|
||||||
updateWrapper.eq(OauthClientDetail::getClientId,clientId);
|
updateWrapper.eq(OauthClientDetail::getClientId, clientId);
|
||||||
oauthClientDetailsMapper.delete(updateWrapper);
|
oauthClientDetailsMapper.delete(updateWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ClientDetails> listClientDetails() {
|
public List<ClientDetails> listClientDetails() {
|
||||||
List<OauthClientDetail> oauthClientDetails = oauthClientDetailsMapper.selectList(Wrappers.emptyWrapper());
|
List<OauthClientDetail> oauthClientDetails = oauthClientDetailsMapper.selectList(Wrappers.emptyWrapper());
|
||||||
if (CollectionUtils.isEmpty(oauthClientDetails)){
|
if (CollectionUtils.isEmpty(oauthClientDetails)) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
return BeanUtils.map(oauthClientDetails,ClientDetails.class);
|
return BeanUtils.map(oauthClientDetails, ClientDetails.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,10 @@ public class CommonRedisKeyConstant {
|
|||||||
*/
|
*/
|
||||||
public static final String REDIS_KEY_PRIVATE_RSA = "rsa:key:private_key";
|
public static final String REDIS_KEY_PRIVATE_RSA = "rsa:key:private_key";
|
||||||
public static final String REDIS_KEY_PUBLIC_RSA = "rsa:key:public_key";
|
public static final String REDIS_KEY_PUBLIC_RSA = "rsa:key:public_key";
|
||||||
|
/**
|
||||||
|
* csrf防护key
|
||||||
|
*/
|
||||||
|
public static final String XSRF_TOKEN = "XSRF_TOKEN:";
|
||||||
|
|
||||||
private CommonRedisKeyConstant() {
|
private CommonRedisKeyConstant() {
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package cn.zyjblogs.starter.oauth.token;
|
package cn.zyjblogs.starter.oauth.token;
|
||||||
|
|
||||||
import cn.zyjblogs.starter.common.autoconfigure.rsa.RsaKeyProperties;
|
import cn.zyjblogs.starter.common.autoconfigure.rsa.RsaKeyProperties;
|
||||||
|
import cn.zyjblogs.starter.common.entity.constant.CommonRedisKeyConstant;
|
||||||
|
import cn.zyjblogs.starter.redis.utils.RedisTemplateHandler;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@ -10,6 +12,7 @@ import org.springframework.security.crypto.password.PasswordEncoder;
|
|||||||
import org.springframework.security.oauth2.provider.token.TokenStore;
|
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.JwtAccessTokenConverter;
|
||||||
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
|
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@ -24,6 +27,7 @@ public class TokenConfig {
|
|||||||
|
|
||||||
private final RsaKeyProperties rsaKeyProperties;
|
private final RsaKeyProperties rsaKeyProperties;
|
||||||
private final OauthAccessTokenConverter oauthAccessTokenConverter;
|
private final OauthAccessTokenConverter oauthAccessTokenConverter;
|
||||||
|
private final RedisTemplateHandler<String, String> redisTemplateHandler;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public PasswordEncoder passwordEncoder() {
|
public PasswordEncoder passwordEncoder() {
|
||||||
@ -46,7 +50,10 @@ public class TokenConfig {
|
|||||||
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
|
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
|
||||||
try {
|
try {
|
||||||
if (rsaKeyProperties.getEnable()) {
|
if (rsaKeyProperties.getEnable()) {
|
||||||
String publicKey = IOUtils.toString(Paths.get(rsaKeyProperties.getPubKeyPath()).toUri(), StandardCharsets.UTF_8);
|
String publicKey = redisTemplateHandler.get(CommonRedisKeyConstant.REDIS_KEY_PUBLIC_RSA);
|
||||||
|
if (!StringUtils.hasLength(publicKey)) {
|
||||||
|
publicKey = IOUtils.toString(Paths.get(rsaKeyProperties.getPubKeyPath()).toUri(), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
// 公钥验签
|
// 公钥验签
|
||||||
converter.setVerifierKey(publicKey);
|
converter.setVerifierKey(publicKey);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user