package com.gkhy.safePlatform.config.security;
|
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.gkhy.safePlatform.account.rpc.apimodel.UserAccountService;
|
import com.gkhy.safePlatform.commons.co.CacheUser;
|
import com.gkhy.safePlatform.commons.enums.RedisKeyEnum;
|
import com.gkhy.safePlatform.commons.enums.ResultCodes;
|
import com.gkhy.safePlatform.commons.exception.BusinessException;
|
import com.gkhy.safePlatform.commons.utils.StringUtils;
|
import com.gkhy.safePlatform.commons.vo.ResultVO;
|
import org.apache.dubbo.config.annotation.DubboReference;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.stereotype.Component;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
|
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 {
|
|
@Autowired
|
private TokenConfig tokenConfig;
|
@DubboReference(check = false)
|
private UserAccountService userAccountService;
|
|
|
|
@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 ResultVO<>(e.getError()));
|
} catch (Exception e) {
|
e.printStackTrace();
|
this.writeJSON(req, resp, new ResultVO<>(ResultCodes.SERVER_ERROR));
|
}
|
|
|
}
|
|
|
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest req,HttpServletResponse resp) {
|
// header获取token
|
String authToken = req.getHeader(tokenConfig.getHeader());
|
String loginUserId = req.getHeader(tokenConfig.getLoginUserHeader());
|
|
if(authToken != null) {
|
// header 传入 userId
|
if (StringUtils.isBlank(loginUserId)) {
|
throw new BusinessException(ResultCodes.CLIENT_CREDENTIALS_LACK);
|
}
|
// 登录成功时,会将权限数据存入redis
|
// 这里是验证获取权限信息
|
// 1.从redis中获取对应该用户的权限信息
|
String accessTokenKey = RedisKeyEnum.authKey(RedisKeyEnum.AUTH_TOKEN, loginUserId);
|
String o = userAccountService.getValueByKeyFromRedis(accessTokenKey);
|
// 2.token是否存在
|
if (o == null) {
|
// 是否存在
|
throw new BusinessException(ResultCodes.CLIENT_CREDENTIALS_SIGN_INVALID);
|
}else{
|
Long userId = Long.valueOf(loginUserId);
|
CacheUser cacheUser = JSONObject.parseObject(o, CacheUser.class);
|
assert userId.equals(cacheUser.getUserId());
|
if ( !authToken.equals(cacheUser.getAccessToken())) {
|
throw new BusinessException(ResultCodes.CLIENT_CREDENTIALS_TOKEN_INVALID);
|
}
|
|
// 3.redis获取权限
|
String authoritiesKey = RedisKeyEnum.authKey(RedisKeyEnum.AUTH_AUTHORITIES, userId);
|
String oo = userAccountService.getValueByKeyFromRedis(authoritiesKey);
|
List<GrantedAuthority> authorities;
|
// 4.redis中是否存在
|
if (oo != null) {
|
// 5.存在
|
authorities = JSONArray.parseArray(oo, GrantedAuthority.class);
|
}else {
|
authorities = new ArrayList<>();
|
// 6.不存在=>数据库查询
|
String roleCode = userAccountService.getUserRoleCodeByUserId(userId);
|
// role
|
authorities.add(new SimpleGrantedAuthority("ROLE_" + roleCode));
|
|
// permission
|
List<String> permissions = userAccountService.getUserPermissionByUserId(userId);
|
for (String permission : permissions) {
|
SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(permission);
|
authorities.add(simpleGrantedAuthority);
|
}
|
}
|
|
// security对象中存入登陆者信息
|
return new UsernamePasswordAuthenticationToken(userId,authToken,authorities);
|
|
}
|
|
|
|
|
|
|
}
|
return null;
|
}
|
|
|
|
protected void writeJSON(HttpServletRequest req,
|
HttpServletResponse resp,
|
ResultVO resultVO) 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();
|
out.write(JSONObject.toJSONString(resultVO));
|
out.flush();
|
out.close();
|
}
|
}
|