优化代码

This commit is contained in:
zhuyijun 2022-10-16 21:19:27 +08:00
parent 46a1b2094d
commit 295cedcaed
7 changed files with 91 additions and 25 deletions

View File

@ -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();
}
}

View File

@ -26,6 +26,7 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
private String resourceId;
private final TokenStore tokenStore;
private final WhiteListProperties whiteListProperties;
// private final CsrfTokenRepository oauthCsrfTokenRepository;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
@ -47,9 +48,8 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
*/
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
http.csrf().disable()
// .disable()
//限制资源服务器作用范围为 "/user/**", "/demo/**"
.requestMatchers().antMatchers("/v*/**", "/demo/**",
String.join(",", whiteListProperties.getAllowPaths()))

View File

@ -20,6 +20,7 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
private final OauthUserDetailsServiceImpl userDetailsService;
private final OauthAuthenticationProvider oauthAuthenticationProvider;
private final PasswordEncoder passwordEncoder;
// private final CsrfTokenRepository oauthCsrfTokenRepository;
/**
* 密码编码解码
*

View File

@ -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.code.AuthorizationCodeServices;
import java.util.concurrent.TimeUnit;
/**
* @author zhuyijun
*/
@ -32,7 +34,9 @@ public class OauthAuthorizationCodeServices implements AuthorizationCodeServices
@Override
public String createAuthorizationCode(OAuth2Authentication oAuth2Authentication) {
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;
}
@ -44,8 +48,10 @@ public class OauthAuthorizationCodeServices implements AuthorizationCodeServices
@SneakyThrows
@Override
public OAuth2Authentication consumeAuthorizationCode(String code) throws InvalidGrantException {
OAuth2Authentication oAuth2Authentication = redisTemplateHandler.<String, OAuth2Authentication>hGet(CommonRedisKeyConstant.AUTHORIZATION_CODE, code);
redisTemplateHandler.hDelete(CommonRedisKeyConstant.AUTHORIZATION_CODE, code);
// OAuth2Authentication oAuth2Authentication = redisTemplateHandler.<String, OAuth2Authentication>hGet(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;
}

View File

@ -5,16 +5,10 @@ import cn.zyjblogs.server.client.po.OauthClientDetail;
import cn.zyjblogs.starter.common.utils.bean.BeanUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientAlreadyExistsException;
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.security.oauth2.provider.*;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@ -31,16 +25,16 @@ public class OauthClientDetailsServiceImpl implements ClientDetailsService, Clie
private final PasswordEncoder passwordEncoder;
@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
public OauthClientDetail loadClientByClientId(String clientId) throws ClientRegistrationException {
LambdaQueryWrapper<OauthClientDetail> wrapper = Wrappers.lambdaQuery();
wrapper.eq(OauthClientDetail::getClientId,clientId);
wrapper.eq(OauthClientDetail::getClientId, clientId);
return oauthClientDetailsMapper.selectOne(wrapper);
}
@Override
public void addClientDetails(ClientDetails clientDetails) throws ClientAlreadyExistsException {
OauthClientDetail oauthClientDetail = new OauthClientDetail(clientDetails);
if (oauthClientDetail.getClientSecret() != null){
if (oauthClientDetail.getClientSecret() != null) {
oauthClientDetail.setClientSecret(passwordEncoder.encode(oauthClientDetail.getClientSecret()));
}
oauthClientDetailsMapper.insert(oauthClientDetail);
@ -49,31 +43,31 @@ public class OauthClientDetailsServiceImpl implements ClientDetailsService, Clie
@Override
public void updateClientDetails(ClientDetails clientDetails) throws NoSuchClientException {
LambdaUpdateWrapper<OauthClientDetail> updateWrapper = Wrappers.lambdaUpdate();
updateWrapper.eq(OauthClientDetail::getClientId,clientDetails.getClientId());
updateWrapper.eq(OauthClientDetail::getClientId, clientDetails.getClientId());
OauthClientDetail oauthClientDetail = new OauthClientDetail(clientDetails);
oauthClientDetailsMapper.update(oauthClientDetail,updateWrapper);
oauthClientDetailsMapper.update(oauthClientDetail, updateWrapper);
}
@Override
public void updateClientSecret(String clientId, String clientSecret) throws NoSuchClientException {
LambdaUpdateWrapper<OauthClientDetail> updateWrapper = Wrappers.lambdaUpdate();
updateWrapper.eq(OauthClientDetail::getClientId,clientId).set(OauthClientDetail::getClientSecret,passwordEncoder.encode(clientSecret));
oauthClientDetailsMapper.update(null,updateWrapper);
updateWrapper.eq(OauthClientDetail::getClientId, clientId).set(OauthClientDetail::getClientSecret, passwordEncoder.encode(clientSecret));
oauthClientDetailsMapper.update(null, updateWrapper);
}
@Override
public void removeClientDetails(String clientId) throws NoSuchClientException {
LambdaUpdateWrapper<OauthClientDetail> updateWrapper = Wrappers.lambdaUpdate();
updateWrapper.eq(OauthClientDetail::getClientId,clientId);
updateWrapper.eq(OauthClientDetail::getClientId, clientId);
oauthClientDetailsMapper.delete(updateWrapper);
}
@Override
public List<ClientDetails> listClientDetails() {
List<OauthClientDetail> oauthClientDetails = oauthClientDetailsMapper.selectList(Wrappers.emptyWrapper());
if (CollectionUtils.isEmpty(oauthClientDetails)){
if (CollectionUtils.isEmpty(oauthClientDetails)) {
return new ArrayList<>();
}
return BeanUtils.map(oauthClientDetails,ClientDetails.class);
return BeanUtils.map(oauthClientDetails, ClientDetails.class);
}
}

View File

@ -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_PUBLIC_RSA = "rsa:key:public_key";
/**
* csrf防护key
*/
public static final String XSRF_TOKEN = "XSRF_TOKEN:";
private CommonRedisKeyConstant() {
}

View File

@ -1,6 +1,8 @@
package cn.zyjblogs.starter.oauth.token;
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 org.apache.commons.io.IOUtils;
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.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@ -24,6 +27,7 @@ public class TokenConfig {
private final RsaKeyProperties rsaKeyProperties;
private final OauthAccessTokenConverter oauthAccessTokenConverter;
private final RedisTemplateHandler<String, String> redisTemplateHandler;
@Bean
public PasswordEncoder passwordEncoder() {
@ -46,7 +50,10 @@ public class TokenConfig {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
try {
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);
}