package com.gkhy.labRiskManage.config.authorization; import com.fasterxml.jackson.databind.ObjectMapper; import com.gkhy.labRiskManage.application.account.dto.respDto.ContextUserDto; import com.gkhy.labRiskManage.application.account.dto.respDto.TokenInfoDto; import com.gkhy.labRiskManage.application.account.dto.respDto.UserInfoAppRespDTO; import com.gkhy.labRiskManage.application.account.service.AccountAppService; import com.gkhy.labRiskManage.application.account.service.TokenAppService; import com.gkhy.labRiskManage.commons.domain.Result; import com.gkhy.labRiskManage.commons.domain.SearchResult; import com.gkhy.labRiskManage.commons.enums.ResultCode; import com.gkhy.labRiskManage.commons.exception.BusinessException; import org.redisson.api.RMapCache; import org.redisson.api.RedissonClient; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import javax.annotation.Resource; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; /** * @Description: token登录过滤器 */ @Component public class TokenAuthenticationFilter extends OncePerRequestFilter { @Resource private TokenConfig tokenConfig; @Autowired private RedissonClient redissonClient; @Autowired private AccountAppService accountAppService; @Autowired private TokenAppService tokenService; @Override protected void doFilterInternal(HttpServletRequest req, HttpServletResponse resp, FilterChain chain) throws IOException, ServletException { try { //获取当前认证成功用户权限信息 UsernamePasswordAuthenticationToken authRequest = getAuthentication(req, resp); if (authRequest != null) { SecurityContextHolder.getContext().setAuthentication(authRequest); } // 执行下一个 filter 过滤器链 chain.doFilter(req, resp); } catch (BusinessException e) { // 返回异常 this.writeJSON(req, resp, new Result<>(e.getCode(),e.getMessage())); } } private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest req,HttpServletResponse resp) { // header获取token String authToken = req.getHeader(tokenConfig.getHeader()); String loginUserId = req.getHeader(tokenConfig.getLoginUserHeader()); RMapCache tokenCacheMap = null; if(authToken != null) { // header 传入 userId if (loginUserId == null || loginUserId.isEmpty()) { throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL); } // 登录成功时,会将权限数据存入redis // 这里是验证获取权限信息 // 1.从redis中获取对应该用户的权限信息 Long userId = Long.parseLong(loginUserId); Result getTokenInfoResult = tokenService.getToken(userId); TokenInfoDto tokenInfoDto = null; if(getTokenInfoResult.isSuccess()){ tokenInfoDto = (TokenInfoDto) getTokenInfoResult.getData(); if(tokenInfoDto == null || tokenInfoDto.getTk() == null || !tokenInfoDto.getTk().equals(authToken)){ throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_PERMISSION_DENIALED); } }else { throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_PERMISSION_DENIALED); } SearchResult userResult = accountAppService.findUserByUserId(userId); if(!userResult.isSuccess() || userResult.getData() == null){ throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_ACCOUNT_NOT_EXIST); } UserInfoAppRespDTO user = (UserInfoAppRespDTO) userResult.getData(); ContextUserDto contextUserDto = new ContextUserDto(); BeanUtils.copyProperties(user,contextUserDto); //获取授权信息 //todo List authorities = new ArrayList<>(); //token续期,提前60分钟 Long tokenRemainTimeToLive = tokenInfoDto.getRemainSecond(); if(tokenRemainTimeToLive/60 <= 60){ tokenService.resetTokenTime(userId); } // security对象中存入登陆者信息 return new UsernamePasswordAuthenticationToken(contextUserDto,authToken,authorities); } return null; } protected void writeJSON(HttpServletRequest req, HttpServletResponse resp, Result result) throws IOException { // 设置编码格式 resp.setContentType("text/json;charset=utf-8"); // 处理跨域问题 resp.setHeader("Access-Control-Allow-Origin", "*"); resp.setHeader("Access-Control-Allow-Methods", "POST, GET"); //输出JSON PrintWriter out = resp.getWriter(); ObjectMapper om = new ObjectMapper(); out.write(om.writeValueAsString(result)); out.flush(); out.close(); } }