package cn.cetc54.platform.core.config.security.jwt;
|
|
import cn.cetc54.platform.core.common.annotation.SystemLog;
|
import cn.cetc54.platform.core.common.enums.LogType;
|
import cn.cetc54.platform.core.common.utils.IpInfoUtil;
|
import cn.cetc54.platform.core.common.utils.ResponseUtil;
|
import cn.cetc54.platform.core.common.constant.SecurityConstant;
|
import cn.cetc54.platform.core.common.vo.TokenUser;
|
import cn.cetc54.platform.core.config.properties.PlatformTokenProperties;
|
import cn.hutool.core.util.StrUtil;
|
import com.google.gson.Gson;
|
import io.jsonwebtoken.Jwts;
|
import io.jsonwebtoken.SignatureAlgorithm;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
import org.springframework.stereotype.Component;
|
|
import javax.servlet.ServletException;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import java.io.IOException;
|
import java.util.ArrayList;
|
import java.util.Date;
|
import java.util.List;
|
import java.util.UUID;
|
import java.util.concurrent.TimeUnit;
|
|
/**
|
* 登录成功处理类
|
* @author
|
*/
|
@Slf4j
|
@Component
|
public class AuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
|
|
@Autowired
|
private PlatformTokenProperties tokenProperties;
|
|
@Autowired
|
private IpInfoUtil ipInfoUtil;
|
|
@Autowired
|
private StringRedisTemplate redisTemplate;
|
|
@Override
|
@SystemLog(description = "登录系统", type = LogType.LOGIN)
|
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
|
|
// 用户选择保存登录状态几天(记住我)
|
String saveLogin = request.getParameter(SecurityConstant.SAVE_LOGIN);
|
Boolean saved = false;
|
if(StrUtil.isNotBlank(saveLogin) && Boolean.valueOf(saveLogin)){
|
saved = true;
|
if(!tokenProperties.getRedis()){
|
tokenProperties.setTokenExpireTime(tokenProperties.getSaveLoginTime() * 60 * 24);
|
}
|
}
|
String username = ((UserDetails)authentication.getPrincipal()).getUsername();
|
List<GrantedAuthority> authorities = (List<GrantedAuthority>) ((UserDetails)authentication.getPrincipal()).getAuthorities();
|
List<String> list = new ArrayList<>();
|
for(GrantedAuthority g : authorities){
|
list.add(g.getAuthority());
|
}
|
ipInfoUtil.getUrl(request);
|
// 登陆成功生成token
|
String token;
|
if(tokenProperties.getRedis()){
|
// redis
|
token = UUID.randomUUID().toString().replace("-", "");
|
TokenUser user = new TokenUser(username, list, saved);
|
// 不缓存权限
|
if(!tokenProperties.getStorePerms()){
|
user.setPermissions(null);
|
}
|
// 单设备登录 之前的token失效
|
if(tokenProperties.getSdl()){
|
String oldToken = redisTemplate.opsForValue().get(SecurityConstant.USER_TOKEN + username);
|
if(StrUtil.isNotBlank(oldToken)){
|
redisTemplate.delete(SecurityConstant.TOKEN_PRE + oldToken);
|
}
|
}
|
if(saved){
|
redisTemplate.opsForValue().set(SecurityConstant.USER_TOKEN + username, token, tokenProperties.getSaveLoginTime(), TimeUnit.DAYS);
|
redisTemplate.opsForValue().set(SecurityConstant.TOKEN_PRE + token, new Gson().toJson(user), tokenProperties.getSaveLoginTime(), TimeUnit.DAYS);
|
}else{
|
redisTemplate.opsForValue().set(SecurityConstant.USER_TOKEN + username, token, tokenProperties.getTokenExpireTime(), TimeUnit.MINUTES);
|
redisTemplate.opsForValue().set(SecurityConstant.TOKEN_PRE + token, new Gson().toJson(user), tokenProperties.getTokenExpireTime(), TimeUnit.MINUTES);
|
}
|
}else{
|
// JWT不缓存权限 避免JWT长度过长
|
list = null;
|
// JWT
|
token = SecurityConstant.TOKEN_SPLIT + Jwts.builder()
|
//主题 放入用户名
|
.setSubject(username)
|
//自定义属性 放入用户拥有请求权限
|
.claim(SecurityConstant.AUTHORITIES, new Gson().toJson(list))
|
//失效时间
|
.setExpiration(new Date(System.currentTimeMillis() + tokenProperties.getTokenExpireTime() * 60 * 1000))
|
//签名算法和密钥
|
.signWith(SignatureAlgorithm.HS512, SecurityConstant.JWT_SIGN_KEY)
|
.compact();
|
}
|
|
ResponseUtil.out(response, ResponseUtil.resultMap(true,200,"登录成功", token));
|
}
|
}
|