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 authorities = (List) ((UserDetails) authentication.getPrincipal()).getAuthorities(); List 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)); } }