今天做了一个冻结/解冻用户的功能,这里记录下思路
1. 冻结
1.修改数据库用户状态信息
2.将用户拉黑状态存入缓存
// 拉黑token
String userKey = CacheName.TOKEN_UNICODE_FROZEN_ORDER + ":" + changeAccountCode;
// 1.2 加入 黑名单
CacheForHash.set(userKey, changeAccountCode, true);
2. 解冻
- 修改数据库用户状态
- 删除用户拉黑缓存
//账户进行解冻操作
int i = accountDao.accountUnfreeze(params);
// 删除拉黑token
String userKey = CacheName.TOKEN_UNICODE_FROZEN_ORDER + ":" + changeAccountCode;
// 1.2 删除 黑名单
CacheForHash.delete(userKey);
3. 拦截
在解析token时,获取缓存信息,查看是否存在拉黑账号
import com.hdx.common.CacheName;
import com.jate.base.cache.CacheForHash;
import com.jate.base.exception.BaseException;
import com.jate.base.util.HttpUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
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.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.UserAuthenticationConverter;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @author jate
* @version 1.0.0
* @Description 资源token解析加载
* @Date 2019/4/4
*/
@Component
@Data
@Slf4j
public class BaseResourceServerTokenServices implements ResourceServerTokenServices {
private TokenStore tokenStore;
private DefaultAccessTokenConverter defaultAccessTokenConverter;
private JwtAccessTokenConverter jwtAccessTokenConverter;
@Resource
private UserAuthenticationConverter userTokenConverter;
@Resource
private IRefreshToken refreshToken;
@Resource
private Redisson redisson;
/**
* 加载token信息 并判断是否过期
*
* @param accessToken
* @return
* @throws AuthenticationException
* @throws InvalidTokenException
*/
@Override
public OAuth2Authentication loadAuthentication(String accessToken)
throws AuthenticationException, InvalidTokenException {
OAuth2Authentication oAuth2Authentication = tokenStore.readAuthentication(accessToken);
defaultAccessTokenConverter.setUserTokenConverter(userTokenConverter);
Map<String, ?> map = jwtAccessTokenConverter.convertAccessToken(readAccessToken(accessToken),
oAuth2Authentication);
long exp = (Long) map.get("exp") * 1000;
long nowDate = System.currentTimeMillis();
String accountCode = (String) map.get("accountCode");
String jti = (String) map.get("jti");
//获取用户是否记住密码
Object remember = map.get("isRemember");
Boolean isRemember = false;
if (remember != null) {
isRemember = Boolean.valueOf(remember.toString());
}
if (exp < nowDate && !isRemember) {
throw new InvalidTokenException("请登录!");
}
if (!map.containsKey("aud")) {
if (CacheForHash.hasKey(CacheName.TOKEN_UNICODE_BLACK_ORDER, jti)) {
throw new InvalidTokenException(TokenCommon.OFFLINE);
} else if (CacheForHash.hasKey(CacheName.TOKEN_UNICODE_FROZEN_ORDER + ":" + accountCode, accountCode)) {
throw new InvalidTokenException(TokenCommon.FROZEN);
}
//记住密码刷新token
if (isRemember) {
exp = (exp - nowDate) / 1000 / 60;
if (exp <= 2) {// 执行刷新token
RLock lock = redisson.getLock("sys:token:" + accountCode);
lock.lock(1000, TimeUnit.MILLISECONDS);
try {
String lastKey = CacheName.USER + accountCode + ":" + jti;
if (CacheForHash.hasKey(lastKey, CacheName.TOKEN)) {
HttpUtil.getResponse().setHeader("access_token",
CacheForHash.get(lastKey, CacheName.TOKEN, String.class));
throw new InvalidTokenException(TokenCommon.REFRESH_TOKEN);
}
int refreshStatus = refreshToken.refreshToken(map);
if (refreshStatus == 1)
throw new BaseException(100, "请登录!");
else if (refreshStatus == 3) {
throw new InvalidTokenException(TokenCommon.REFRESH_TOKEN);
}
} catch (InvalidTokenException e) {
throw new InvalidTokenException(TokenCommon.REFRESH_TOKEN);
} catch (BaseException e) {
throw new InvalidTokenException("请登录!");
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
lock.unlock();
}
}
}
}
try {
HttpServletRequest request = HttpUtil.getRequest();
request.setAttribute("jti", jti);//登录后的唯一签名标识
request.setAttribute("accountCode", map.get("accountCode"));//用户唯一标识
request.setAttribute("subAccountCode", map.get("subAccount"));//用户唯一标识
} catch (Exception e) {
}
return defaultAccessTokenConverter.extractAuthentication(map);
}
/**
* 读取token
*
* @param accessToken
* @return
*/
@Override
public OAuth2AccessToken readAccessToken(String accessToken) {
return tokenStore.readAccessToken(accessToken);
}
}