package com.gkhy.testFourierSpecialGasMonitor.config.authorization;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.gkhy.testFourierSpecialGasMonitor.application.account.dto.respDto.ContextUserDto;
|
import com.gkhy.testFourierSpecialGasMonitor.application.account.dto.respDto.TokenInfoDto;
|
import com.gkhy.testFourierSpecialGasMonitor.application.account.dto.respDto.UserInfoAppRespDTO;
|
import com.gkhy.testFourierSpecialGasMonitor.application.account.service.AccountAppService;
|
import com.gkhy.testFourierSpecialGasMonitor.application.account.service.TokenAppService;
|
import com.gkhy.testFourierSpecialGasMonitor.commons.domain.Result;
|
import com.gkhy.testFourierSpecialGasMonitor.commons.domain.SearchResult;
|
import com.gkhy.testFourierSpecialGasMonitor.commons.enums.ResultCode;
|
import com.gkhy.testFourierSpecialGasMonitor.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<String,Object> tokenCacheMap = null;
|
|
//外部接口只能携带专门token访问特定的几个接口
|
if (req.getRequestURI().startsWith("/api")){
|
if (tokenConfig.getExternalAccessKey().equals(req.getHeader(tokenConfig.getExternalAccessHeader()))){
|
return new UsernamePasswordAuthenticationToken(null,null,null);
|
}
|
throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_PERMISSION_DENIALED);
|
}
|
|
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<TokenInfoDto> 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<UserInfoAppRespDTO> 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<GrantedAuthority> 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();
|
}
|
}
|