项目中使用spring-security实现的oauth2认证,需要集成第三方的单点登录。第三方登录成功后采用反向代理的方式将用户信息存在请求头中传递给应用系统,应用系统需要根据请求头验证请求并做出相应的跳转。
实现思路
1.重新RequestWrapper中的方法
public class RequestWrapper extends HttpServletRequestWrapper {
private static final Logger logger = LoggerFactory.getLogger(RequestWrapper.class);
private Map<String,String> headerMap=new HashMap<>();
@Override
public Enumeration<String> getHeaderNames() {
List<String> names = Collections.list(super.getHeaderNames());
for (String name : headerMap.keySet()) {
names.add(name);
}
return Collections.enumeration(names);
}
public RequestWrapper(HttpServletRequest request) {
super(request);
}
public void addHeader(String name, String value) {
headerMap.put(name, value);
}
public void removeHeader(String name) {
headerMap.remove(name);
}
@Override
public String getHeader(String name) {
String headerValue = super.getHeader(name);
if (headerMap.containsKey(name)) {
headerValue = headerMap.get(name);
}
return headerValue;
}
@Override
public Enumeration<String> getHeaders(String name) {
List<String> values = Collections.list(super.getHeaders(name));
if (headerMap.containsKey(name)) {
values = Arrays.asList(headerMap.get(name));
}
return Collections.enumeration(values);
}
2.定义Filter拦截请求
@Component
public class IntegrationAuthenticationFilter extends GenericFilterBean {
private static final Logger logger = LoggerFactory.getLogger(IntegrationAuthenticationFilter.class);
//private ApplicationContext applicationContext;
@Autowired
ResourceServerTokenServices myUserInfoTokenServices;
//@Value("${WebSEAL.ip}")
//String webSeal_ip;
private String username = "admin";
private String password = "admin";
private final String gwt_username = "Open-Care";
private final String gwt_password = "opencare";
@Autowired
MessageService messageService;
@Autowired
JWTGenerateService jwtGenerateService;
RequestWrapper requestWrapper=null;
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 获取发送请求的机器IP
String remoteAddr=request.getRemoteAddr();
// 用户名
String iv_user=request.getHeader("iv-user");
// 所属组织名称
String iv_groups=request.getHeader("iv-groups");
// 当前用户访问的域名
String ssodomainname=request.getHeader("ssodomainname");
// 当前请求所用的协议
String ssoprotocol=request.getHeader("ssoprotocol");
// 客户端IP
String ssoclientip=request.getHeader("ssoclientip");
// 验证请求IP地址和用户名
if (StringUtils.isNotEmpty(remoteAddr) && StringUtils.isNotEmpty(iv_user)) {
// 验证IP地址
boolean validIP=verifyRequestIPHasValid(remoteAddr);
// 验证用户名
boolean validUsername=verifyUserNameHasExist(iv_user);
if (validIP && validUsername) {
try {
if (requestWrapper == null) {
requestWrapper=requestWrapper(request);
chain.doFilter(requestWrapper, response);
}else {
chain.doFilter(requestWrapper, response);
}
}catch (Exception e) {
e.printStackTrace();
}
} else {
if (!validUsername) {
throw new ServiceException("用户名不正确");
}
if (!validIP) {
throw new ServiceException("非法访问");
}
//chain.doFilter(requestWrapper,response);
}
}else {
requestWrapper=null;
chain.doFilter(request,response);
}
}
private boolean verifyUserNameHasExist(String iv_user) {
// 查询用户是否存在
return false;
}
private boolean verifyRequestIPHasValid(String request_ip) {
// 验证IP 是否合法的 WebSEALL真实服务器IP地址
return true;
}
private RequestWrapper requestWrapper(HttpServletRequest request) {
logger.info(" wrapper request start ");
RequestWrapper requestWrapper=new RequestWrapper(request);
String token = messageService.getAccessToken();
//验证jwt token
JWTAppUserInfoTokenServices jwtAppUserInfoTokenServices = ((JWTAppUserInfoTokenServices) myUserInfoTokenServices);
// 根据token获取用户
Map<String, Object> userInfoMap = jwtAppUserInfoTokenServices.getUserInfoMap(token);
// 模拟用户登录
AnonymousAuthenticationToken anonymousAuthenticationToken = jwtAppUserInfoTokenServices.makeAnonymousAuthenticationToken(userInfoMap);
SecurityContextHolder.getContext().setAuthentication(anonymousAuthenticationToken);
requestWrapper.addHeader("Authorization", token);
logger.info("wrapper request end ,token is "+token);
return requestWrapper;
}
}