Skip to content

Commit 327e542

Browse files
committed
add #40
1 parent 2e9092b commit 327e542

17 files changed

+166
-48
lines changed

springboot-starter-security/pom.xml

+6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@
3030
<artifactId>spring-boot-starter-web</artifactId>
3131
</dependency>
3232

33+
<dependency>
34+
<groupId>org.springframework.boot</groupId>
35+
<artifactId>spring-boot-starter-data-redis</artifactId>
36+
<scope>provided</scope>
37+
</dependency>
38+
3339
<dependency>
3440
<groupId>io.jsonwebtoken</groupId>
3541
<artifactId>jjwt-api</artifactId>

springboot-starter-security/src/main/java/com/codingapi/springboot/security/jwt/MyAES.java renamed to springboot-starter-security/src/main/java/com/codingapi/springboot/security/crypto/AESTools.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1-
package com.codingapi.springboot.security.jwt;
1+
package com.codingapi.springboot.security.crypto;
22

33
import com.codingapi.springboot.framework.crypto.AES;
44
import lombok.SneakyThrows;
55

66
import java.nio.charset.StandardCharsets;
77
import java.util.Base64;
88

9-
public class MyAES {
9+
public class AESTools {
1010

11-
private final static MyAES instance = new MyAES();
11+
private final static AESTools instance = new AESTools();
1212

1313
private AES aes;
1414

15-
private MyAES() {
15+
private AESTools() {
1616
}
1717

1818
void init(AES aes) {
1919
this.aes = aes;
2020
}
2121

22-
public static MyAES getInstance() {
22+
public static AESTools getInstance() {
2323
return instance;
2424
}
2525

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.codingapi.springboot.security.crypto;
2+
3+
import com.codingapi.springboot.framework.crypto.AES;
4+
import com.codingapi.springboot.security.properties.CodingApiSecurityProperties;
5+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
6+
import org.springframework.context.annotation.Bean;
7+
import org.springframework.context.annotation.Configuration;
8+
9+
import java.util.Base64;
10+
11+
@Configuration
12+
public class SecurityCryptoConfiguration {
13+
14+
@Bean
15+
@ConditionalOnMissingBean
16+
public AES aes(CodingApiSecurityProperties properties) throws Exception {
17+
AES aes = new AES(Base64.getDecoder().decode(properties.getAseKey().getBytes()),
18+
Base64.getDecoder().decode(properties.getAseIv()));
19+
AESTools.getInstance().init(aes);
20+
return aes;
21+
}
22+
}

springboot-starter-security/src/main/java/com/codingapi/springboot/security/filter/MyAuthenticationFilter.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import com.alibaba.fastjson.JSONObject;
44
import com.codingapi.springboot.framework.dto.response.Response;
55
import com.codingapi.springboot.security.exception.TokenExpiredException;
6-
import com.codingapi.springboot.security.gateway.TokenGateway;
76
import com.codingapi.springboot.security.gateway.Token;
7+
import com.codingapi.springboot.security.gateway.TokenGateway;
88
import com.codingapi.springboot.security.properties.CodingApiSecurityProperties;
99
import jakarta.servlet.FilterChain;
1010
import jakarta.servlet.ServletException;
@@ -45,7 +45,7 @@ public MyAuthenticationFilter(AuthenticationManager manager, CodingApiSecurityPr
4545
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
4646
log.debug("token authentication ~");
4747
for (String antUrl : securityJwtProperties.getAuthenticatedUrls()) {
48-
if(antPathMatcher.match(antUrl,request.getRequestURI())) {
48+
if (antPathMatcher.match(antUrl, request.getRequestURI())) {
4949

5050
String sign = request.getHeader(TOKEN_KEY);
5151
if (!StringUtils.hasLength(sign)) {
@@ -54,6 +54,10 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
5454
}
5555

5656
Token token = tokenGateway.parser(sign);
57+
if (token == null) {
58+
writeResponse(response, Response.buildFailure("token.expire", "token expire."));
59+
return;
60+
}
5761
if (token.canRestToken()) {
5862
Token newSign = tokenGateway.create(token.getUsername(), token.decodeIv(), token.getAuthorities(), token.getExtra());
5963
log.info("reset token ");

springboot-starter-security/src/main/java/com/codingapi/springboot/security/gateway/Token.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import com.alibaba.fastjson.JSONObject;
44
import com.codingapi.springboot.framework.serializable.JsonSerializable;
5-
import com.codingapi.springboot.security.jwt.MyAES;
5+
import com.codingapi.springboot.security.crypto.AESTools;
66
import com.codingapi.springboot.security.exception.TokenExpiredException;
77
import lombok.Getter;
88
import lombok.NoArgsConstructor;
@@ -34,7 +34,7 @@ public Token(String username, String iv,String extra, List<String> authorities,
3434
this.username = username;
3535
this.extra = extra;
3636
if(iv!=null) {
37-
this.iv = MyAES.getInstance().encode(iv);
37+
this.iv = AESTools.getInstance().encode(iv);
3838
}
3939
this.authorities = authorities;
4040
this.expireTime = System.currentTimeMillis() + expireValue;
@@ -56,7 +56,7 @@ public String decodeIv(){
5656
if(iv==null){
5757
return null;
5858
}
59-
return MyAES.getInstance().decode(iv);
59+
return AESTools.getInstance().decode(iv);
6060
}
6161

6262

springboot-starter-security/src/main/java/com/codingapi/springboot/security/gateway/TokenGateway.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
public interface TokenGateway {
66

7-
Token create(String username, String password, List<String> authorities, String extra);
7+
Token create(String username, String iv, List<String> authorities, String extra);
88

9-
default Token create(String username, String password, List<String> authorities) {
10-
return create(username, password, authorities, null);
9+
default Token create(String username, String iv, List<String> authorities) {
10+
return create(username, iv, authorities, null);
1111
}
1212

1313
default Token create(String username, List<String> authorities) {

springboot-starter-security/src/main/java/com/codingapi/springboot/security/jwt/JWTSecurityConfiguration.java

-11
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,16 @@
11
package com.codingapi.springboot.security.jwt;
22

3-
import com.codingapi.springboot.framework.crypto.AES;
43
import com.codingapi.springboot.security.gateway.TokenGateway;
54
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
65
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
76
import org.springframework.boot.context.properties.ConfigurationProperties;
87
import org.springframework.context.annotation.Bean;
98
import org.springframework.context.annotation.Configuration;
109

11-
import java.util.Base64;
12-
1310
@Configuration
1411
@ConditionalOnProperty(prefix = "codingapi.security.jwt", name = "enable", havingValue = "true", matchIfMissing = true)
1512
public class JWTSecurityConfiguration {
1613

17-
@Bean
18-
@ConditionalOnMissingBean
19-
public AES aes(SecurityJWTProperties properties) throws Exception {
20-
AES aes = new AES(Base64.getDecoder().decode(properties.getAseKey().getBytes()),
21-
Base64.getDecoder().decode(properties.getAseIv()));
22-
MyAES.getInstance().init(aes);
23-
return aes;
24-
}
2514

2615
@Bean
2716
@ConfigurationProperties(prefix = "codingapi.security.jwt")

springboot-starter-security/src/main/java/com/codingapi/springboot/security/jwt/JWTTokenGatewayImpl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public class JWTTokenGatewayImpl implements TokenGateway {
1010
private final Jwt jwt;
1111

1212
public JWTTokenGatewayImpl(SecurityJWTProperties properties) {
13-
this.jwt = new Jwt(properties.getSecretKey(), properties.getJwtTime(), properties.getJwtRestTime());
13+
this.jwt = new Jwt(properties.getSecretKey(), properties.getValidTime(), properties.getRestTime());
1414
}
1515

1616
@Override

springboot-starter-security/src/main/java/com/codingapi/springboot/security/jwt/Jwt.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@
1515
public class Jwt {
1616

1717
private final SecretKey key;
18-
private final int jwtTime;
19-
private final int jwtRestTime;
18+
private final int validTime;
19+
private final int restTime;
2020

21-
public Jwt(String secretKey, int jwtTime, int jwtRestTime) {
21+
public Jwt(String secretKey, int validTime, int restTime) {
2222
this.key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));
23-
this.jwtTime = jwtTime;
24-
this.jwtRestTime = jwtRestTime;
23+
this.validTime = validTime;
24+
this.restTime = restTime;
2525
}
2626

2727
public Token create(String username, List<String> authorities, String extra){
@@ -37,7 +37,7 @@ public Token create(String username, String iv, List<String> authorities){
3737
}
3838

3939
public Token create(String username, String iv,List<String> authorities,String extra){
40-
Token token = new Token(username, iv,extra, authorities, jwtTime, jwtRestTime);
40+
Token token = new Token(username, iv,extra, authorities, validTime, restTime);
4141
String jwt = Jwts.builder().subject(token.toJson()).signWith(key).compact();
4242
token.setToken(jwt);
4343
return token;

springboot-starter-security/src/main/java/com/codingapi/springboot/security/jwt/SecurityJWTProperties.java

+2-13
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,16 @@ public class SecurityJWTProperties {
2020
private String secretKey = "codingapi.security.jwt.secretkey";
2121

2222

23-
/**
24-
* aes key
25-
*/
26-
private String aseKey = "QUNEWCQlXiYqJCNYQ1phc0FDRFgkJV4mKiQjWENaYXM=";
27-
28-
/**
29-
* aes iv
30-
*/
31-
private String aseIv = "QUNYRkdIQEVEUyNYQ1phcw==";
32-
33-
3423
/**
3524
* JWT 有效时间(毫秒)
3625
* 15分钟有效期 1000*60*15=900000
3726
*/
38-
private int jwtTime = 900000;
27+
private int validTime = 900000;
3928

4029
/**
4130
* JWT 更换令牌时间(毫秒)
4231
* 10分钟后更换令牌 1000*60*10=600000
4332
*/
44-
private int jwtRestTime = 600000;
33+
private int restTime = 600000;
4534

4635
}

springboot-starter-security/src/main/java/com/codingapi/springboot/security/properties/CodingApiSecurityProperties.java

+11
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,17 @@ public class CodingApiSecurityProperties {
2828
*/
2929
private String ignoreUrls = "/open/**";
3030

31+
/**
32+
* aes key
33+
*/
34+
private String aseKey = "QUNEWCQlXiYqJCNYQ1phc0FDRFgkJV4mKiQjWENaYXM=";
35+
36+
/**
37+
* aes iv
38+
*/
39+
private String aseIv = "QUNYRkdIQEVEUyNYQ1phcw==";
40+
41+
3142
/**
3243
* 启用禁用CSRF
3344
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.codingapi.springboot.security.redis;
2+
3+
import com.codingapi.springboot.security.gateway.Token;
4+
import com.codingapi.springboot.security.gateway.TokenGateway;
5+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
6+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
7+
import org.springframework.boot.context.properties.ConfigurationProperties;
8+
import org.springframework.context.annotation.Bean;
9+
import org.springframework.context.annotation.Configuration;
10+
import org.springframework.data.redis.core.RedisTemplate;
11+
12+
@Configuration
13+
@ConditionalOnProperty(prefix = "codingapi.security.redis", name = "enable", havingValue = "true")
14+
public class RedisSecurityConfiguration {
15+
16+
17+
@Bean
18+
@ConfigurationProperties(prefix = "codingapi.security.redis")
19+
public SecurityRedisProperties securityRedisProperties() {
20+
return new SecurityRedisProperties();
21+
}
22+
23+
24+
@Bean
25+
@ConditionalOnMissingBean
26+
public TokenGateway redisTokenGateway(RedisTemplate<String, Token> redisTemplate, SecurityRedisProperties properties) {
27+
return new RedisTokenGatewayImpl(redisTemplate, properties);
28+
}
29+
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.codingapi.springboot.security.redis;
2+
3+
import com.codingapi.springboot.security.gateway.Token;
4+
import com.codingapi.springboot.security.gateway.TokenGateway;
5+
import org.springframework.data.redis.core.RedisTemplate;
6+
7+
import java.util.List;
8+
import java.util.UUID;
9+
10+
public class RedisTokenGatewayImpl implements TokenGateway {
11+
12+
private final RedisTemplate<String, Token> redisTemplate;
13+
private final int validTime;
14+
private final int restTime;
15+
16+
public RedisTokenGatewayImpl(RedisTemplate<String, Token> redisTemplate, SecurityRedisProperties properties) {
17+
this.redisTemplate = redisTemplate;
18+
this.validTime = properties.getValidTime();
19+
this.restTime = properties.getRestTime();
20+
}
21+
22+
@Override
23+
public Token create(String username, String iv, List<String> authorities, String extra) {
24+
Token token = new Token(username, iv, extra, authorities, validTime, restTime);
25+
String key = String.format("%s:%s", username, UUID.randomUUID().toString().replaceAll("-", ""));
26+
token.setToken(key);
27+
redisTemplate.opsForValue().set(key, token);
28+
return token;
29+
}
30+
31+
@Override
32+
public Token parser(String sign) {
33+
return redisTemplate.opsForValue().get(sign);
34+
}
35+
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.codingapi.springboot.security.redis;
2+
3+
import lombok.Getter;
4+
import lombok.Setter;
5+
6+
@Setter
7+
@Getter
8+
public class SecurityRedisProperties {
9+
10+
11+
/**
12+
* 是否启用redis
13+
*/
14+
private boolean enable = true;
15+
16+
/**
17+
* 15分钟有效期 1000*60*15=900000
18+
*/
19+
private int validTime = 900000;
20+
21+
/**
22+
* 10分钟后更换令牌 1000*60*10=600000
23+
*/
24+
private int restTime = 600000;
25+
26+
27+
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
22
com.codingapi.springboot.security.configurer.WebSecurityConfigurer,\
33
com.codingapi.springboot.security.jwt.JWTSecurityConfiguration,\
4+
com.codingapi.springboot.security.redis.RedisSecurityConfiguration,\
5+
com.codingapi.springboot.security.crypto.SecurityCryptoConfiguration,\
46
com.codingapi.springboot.security.AutoConfiguration
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
com.codingapi.springboot.security.configurer.WebSecurityConfigurer
2+
com.codingapi.springboot.security.crypto.SecurityCryptoConfiguration
23
com.codingapi.springboot.security.jwt.JWTSecurityConfiguration
4+
com.codingapi.springboot.security.redis.RedisSecurityConfiguration
35
com.codingapi.springboot.security.AutoConfiguration

springboot-starter-security/src/test/resources/application.properties

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
server.port=8088
22

3-
codingapi.security.jwt.jwt-time=10000
4-
codingapi.security.jwt.jwt-rest-time=5000
3+
codingapi.security.jwt.valid-time=10000
4+
codingapi.security.jwt.rest-time=5000
55

66
codingapi.security.jwt.enable=true
77
# JWT密钥 需大于32位的字符串
88
codingapi.security.jwt.secret-key=codingapi.security.jwt.secretkey
99
# JWT AES密钥
10-
codingapi.security.jwt.ase-key=QUNEWCQlXiYqJCNYQ1phc0FDRFgkJV4mKiQjWENaYXM=
10+
codingapi.security.ase-key=QUNEWCQlXiYqJCNYQ1phc0FDRFgkJV4mKiQjWENaYXM=
1111
# JWT AES IV
12-
codingapi.security.jwt.ase-iv=QUNYRkdIQEVEUyNYQ1phcw==
12+
codingapi.security.ase-iv=QUNYRkdIQEVEUyNYQ1phcw==
1313

1414
# JWT 有效时间(毫秒) 15分钟有效期 1000*60*15=900000
1515
#codingapi.security.jwt-time=900000

0 commit comments

Comments
 (0)