Redis jti repository impl/ test

jti-redis-3.0.1
shengzhaoli.shengz 2025-05-28 17:46:38 +08:00
parent a5592cf054
commit 688c47a6f6
7 changed files with 269 additions and 2 deletions

View File

@ -65,6 +65,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>

View File

@ -39,7 +39,8 @@ public class ClaimsOAuth2TokenCustomizer implements OAuth2TokenCustomizer<JwtEnc
JwtClaimsSet.Builder claims = context.getClaims();
//jti
claims.id(GuidGenerator.generateNumber());
String jti = GuidGenerator.generateNumber();
claims.id(jti);
//根据不同的 scope 与 tokenType添加扩展属性
OAuth2TokenType tokenType = context.getTokenType();

View File

@ -0,0 +1,44 @@
package com.monkeyk.sos.domain.oauth;
/**
* 2025/5/28 17:19
*
* @author Shengzhao Li
* @since 3.0.1
*/
public interface JtiRepository {
/**
* JtiToken
*
* @param jtiToken JtiToken
* @param ttl ,
*/
void saveJtiToken(JtiToken jtiToken, long ttl);
/**
*
*
* @param jti jti
* @return JtiToken
*/
JtiToken findByJti(String jti);
/**
* jti () jti
*
* @param jti jti
* @return true
*/
boolean existJti(String jti);
/**
* Jti
*
* @param jti jti
* @return true
*/
Boolean removeJtiToken(String jti);
}

View File

@ -0,0 +1,73 @@
package com.monkeyk.sos.domain.oauth;
import java.io.Serial;
import java.io.Serializable;
/**
* 2025/5/28 17:16
*
* @author Shengzhao Li
* @since 3.0.0
*/
public class JtiToken implements Serializable {
@Serial
private static final long serialVersionUID = -6826558386135443094L;
/**
* jtiid_token
*/
private String jti;
/**
* OAuth2 clientId
*/
private String clientId;
/**
* user id
*/
private String userId;
// 可扩展其他属性
public JtiToken() {
}
public String getJti() {
return jti;
}
public JtiToken setJti(String jti) {
this.jti = jti;
return this;
}
public String getClientId() {
return clientId;
}
public JtiToken setClientId(String clientId) {
this.clientId = clientId;
return this;
}
public String getUserId() {
return userId;
}
public JtiToken setUserId(String userId) {
this.userId = userId;
return this;
}
@Override
public String toString() {
return "{" +
"jti='" + jti + '\'' +
", clientId='" + clientId + '\'' +
", userId='" + userId + '\'' +
'}';
}
}

View File

@ -0,0 +1,96 @@
package com.monkeyk.sos.infrastructure.redis;
import com.monkeyk.sos.domain.oauth.JtiRepository;
import com.monkeyk.sos.domain.oauth.JtiToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;
import java.util.concurrent.TimeUnit;
/**
* 2025/5/28 17:22
*
* @author Shengzhao Li
* @since 3.0.1
*/
@Repository
public class JtiRepositoryRedis implements JtiRepository {
private static final Logger LOG = LoggerFactory.getLogger(JtiRepositoryRedis.class);
/**
* KEY
*/
private static final String KEY_FORMAT = "sos-jti-%s";
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
/**
*
*
* @param jti jti
* @return redis key
*/
private String getJtiRedisKey(String jti) {
return String.format(KEY_FORMAT, jti);
}
/**
* {@inheritDoc}
*/
@Override
public void saveJtiToken(JtiToken jtiToken, long ttl) {
if (ttl <= 0) {
throw new IllegalArgumentException("ttl must be greater than 0");
}
String redisKey = getJtiRedisKey(jtiToken.getJti());
if (LOG.isTraceEnabled()) {
LOG.trace("saveJtiToken, jtiToken: {}, ttl: {}", jtiToken, ttl);
}
BoundValueOperations<Object, Object> bvo = this.redisTemplate.boundValueOps(redisKey);
bvo.set(jtiToken, ttl, TimeUnit.SECONDS);
}
/**
* {@inheritDoc}
*/
@Override
public JtiToken findByJti(String jti) {
String redisKey = getJtiRedisKey(jti);
BoundValueOperations<Object, Object> bvo = this.redisTemplate.boundValueOps(redisKey);
return (JtiToken) bvo.get();
}
/**
* {@inheritDoc}
*/
@Override
public boolean existJti(String jti) {
String redisKey = getJtiRedisKey(jti);
Boolean has = this.redisTemplate.hasKey(redisKey);
return has != null ? has : false;
}
/**
* {@inheritDoc}
*/
@Override
public Boolean removeJtiToken(String jti) {
String redisKey = getJtiRedisKey(jti);
return this.redisTemplate.delete(redisKey);
}
}

View File

@ -24,11 +24,12 @@ spring.security.oauth2.authorizationserver.issuer=http://127.0.0.1:${server.port
#
# Redis
#
spring.data.redis.host=localhost
spring.data.redis.host=127.0.0.1
spring.data.redis.port=6379
spring.data.redis.database=5
spring.data.redis.password=
spring.data.redis.timeout=2000
spring.data.redis.lettuce.pool.enabled=true
#
# Condition Config
# @since 2.1.0

View File

@ -0,0 +1,48 @@
package com.monkeyk.sos.infrastructure.redis;
import com.monkeyk.sos.domain.oauth.JtiToken;
import com.monkeyk.sos.infrastructure.AbstractRepositoryTest;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import static org.junit.jupiter.api.Assertions.*;
/**
* 2025/5/28 17:33
*
* @author Shengzhao Li
* @since 3.0.1
*/
//@Transactional
class JtiRepositoryRedisTest extends AbstractRepositoryTest {
@Autowired
private JtiRepositoryRedis repositoryRedis;
@Test
void saveJtiToken() {
JtiToken jtiToken = new JtiToken()
.setJti("jti").setClientId("clientId").setUserId("userId");
repositoryRedis.saveJtiToken(jtiToken, 1000);
repositoryRedis.removeJtiToken(jtiToken.getJti());
}
@Test
void findByJti() {
JtiToken jtiToken = repositoryRedis.findByJti("jti");
assertNull(jtiToken);
}
@Test
void existJti() {
boolean exist = repositoryRedis.existJti("jti");
assertFalse(exist);
}
}