package cn.exrick.xboot.core.config.security.jwt;
|
|
import cn.exrick.xboot.core.common.annotation.SystemLog;
|
import cn.exrick.xboot.core.common.constant.SecurityConstant;
|
import cn.exrick.xboot.core.common.enums.LogType;
|
import cn.exrick.xboot.core.common.redis.RedisTemplateHelper;
|
import cn.exrick.xboot.core.common.utils.IpInfoUtil;
|
import cn.exrick.xboot.core.common.utils.ResponseUtil;
|
import cn.exrick.xboot.core.common.vo.TokenUser;
|
import cn.exrick.xboot.core.config.properties.XbootTokenProperties;
|
import cn.hutool.core.util.IdUtil;
|
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.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.concurrent.TimeUnit;
|
|
/**
|
* 登录成功处理类
|
* @author Exrickx
|
*/
|
@Slf4j
|
@Component
|
public class AuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
|
|
@Autowired
|
private XbootTokenProperties tokenProperties;
|
|
@Autowired
|
private IpInfoUtil ipInfoUtil;
|
|
@Autowired
|
private RedisTemplateHelper 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.getInfo(request, "");
|
// 登陆成功生成token
|
String token;
|
if (tokenProperties.getRedis()) {
|
// redis
|
token = IdUtil.simpleUUID();
|
TokenUser user = new TokenUser(username, list, saved);
|
// 不缓存权限
|
if (!tokenProperties.getStorePerms()) {
|
user.setPermissions(null);
|
}
|
// 单设备登录 之前的token失效
|
if (tokenProperties.getSdl()) {
|
String oldToken = redisTemplate.get(SecurityConstant.USER_TOKEN + username);
|
if (StrUtil.isNotBlank(oldToken)) {
|
redisTemplate.delete(SecurityConstant.TOKEN_PRE + oldToken);
|
}
|
}
|
if (saved) {
|
redisTemplate.set(SecurityConstant.USER_TOKEN + username, token, tokenProperties.getSaveLoginTime(), TimeUnit.DAYS);
|
redisTemplate.set(SecurityConstant.TOKEN_PRE + token, new Gson().toJson(user), tokenProperties.getSaveLoginTime(), TimeUnit.DAYS);
|
} else {
|
redisTemplate.set(SecurityConstant.USER_TOKEN + username, token, tokenProperties.getTokenExpireTime(), TimeUnit.MINUTES);
|
redisTemplate.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));
|
}
|
}
|