package com.xkrs.common.account; import com.xkrs.common.encapsulation.OutputEncapsulation; import com.xkrs.common.encapsulation.PromptMessageEnum; import com.xkrs.model.entity.SysUserEntity; import com.xkrs.model.vo.SysUserVo; import com.xkrs.utils.DateTimeUtil; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.security.Keys; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.AuthorityUtils; import javax.crypto.SecretKey; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.time.Duration; import java.time.LocalDateTime; import java.util.*; /** * token认证服务 * @author tajochen */ public class TokenAuthenticationService { private static final Logger logger = LoggerFactory.getLogger(TokenAuthenticationService.class); /** * 加密密钥 */ static public final String SECRET_KEY = "0Y9H364Q9Y908262F25LMXGIKIN5N858XM3674GWL2DD8X1DS4W6I722IRY8PS4XPNB6U303" + "45HBVCUL94STG8C3Z53T7A09JJ100I56YE9894CI11PX9J71HIZ8L5Y2O504C4E2K8276425UA8734833F45K36878FXAG799QV9LXU" + "JOI3XA2046UPG8TB2OT84R5T6ZB127N9ZPJ7AJMC41JVHB2WK2B6H8NL45LZNAZ666KHZH3QUT65UX6F8"; /** * Token前缀 */ static public final String TOKEN_PREFIX = "Bearer"; /** * 存放Token的Header Key */ static final String HEADER_STRING = "Authorization"; static SecretKey key = Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); /** * JWT生成方法 * @param response * @param userName * @param authorities */ static void addAuthentication(HttpServletResponse response, String userName, Collection authorities, SysUserVo sysUserEntity) { Locale locale = new Locale("zh", "CN"); Map map = new HashMap(3); StringBuffer auths = new StringBuffer(); String authsList = ""; for(GrantedAuthority r : authorities) { auths.append("," + r.getAuthority()); } authsList = auths.toString(); if(authsList.length()>1){ authsList=authsList.substring(1,authsList.length()); }else{ logger.warn(userName +" has no permission!"); } if(sysUserEntity.getDayNum() == 7){ // 结束的时间 LocalDateTime overTime = DateTimeUtil.stringToDateTime(sysUserEntity.getOverTime()); // 计算距离结束时间的天数作为token Duration duration = Duration.between(LocalDateTime.now(), overTime); System.out.println("-------"+duration.toDays()); /** * 动态设置过期时间 */ final long EXPIRATIONTIME = 60 * 60 * 24 * duration.toDays(); // 生成JWT String jwt = Jwts.builder() .setSubject(userName) .setIssuer("https://www.microservice.com") .setAudience(userName) // 保存权限 .claim("auths", authsList) // 有效期设置 .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME)) // 签名设置 .signWith(key) .compact(); map.put("token",jwt); map.put("role",authsList); map.put("user",sysUserEntity); }else { /** * 过期时间6小时 */ final long EXPIRATIONTIME = 21_600_000; // 生成JWT String jwt = Jwts.builder() .setSubject(userName) .setIssuer("https://www.microservice.com") .setAudience(userName) // 保存权限 .claim("auths", authsList) // 有效期设置 .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME)) // 签名设置 .signWith(key) .compact(); map.put("token",jwt); map.put("role",authsList); map.put("user",sysUserEntity); } // 将 JWT 写入 body PrintWriter out = null; try { out = response.getWriter(); } catch (IOException e) { e.printStackTrace(); } response.setStatus(HttpServletResponse.SC_OK); out.append(OutputEncapsulation.outputEncapsulationObject(PromptMessageEnum.SUCCESS, map, locale)); } /** * JWT验证方法 * @param request * @return */ static Authentication getAuthentication(HttpServletRequest request) { // 从Header中拿到token String token = request.getHeader(HEADER_STRING); if (token != null) { try { // 解析 Token Claims claims = Jwts.parserBuilder() .setSigningKey(key).build() // 去掉 Bearer .parseClaimsJws(token.replace(TOKEN_PREFIX, "")) .getBody(); // 获取用户名 String userName = claims.getSubject(); // 获取权限 List authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get("auths")); return new UsernamePasswordAuthenticationToken(userName, null, authorities); } catch(Exception e) { // the sub field was missing or did not have a value return null; } } else { return null; } } }