PreAuthTokenFilter.java
package cn.home1.oss.lib.security.internal.preauth;
import static cn.home1.oss.lib.security.api.GenericUser.GENERIC_USER_COOKIE;
import static cn.home1.oss.lib.security.api.GenericUser.GENERIC_USER_TOKEN;
import static cn.home1.oss.lib.security.api.Security.HEADER_AUTH_TOKEN;
import static lombok.AccessLevel.PROTECTED;
import cn.home1.oss.lib.security.api.GenericUser;
import cn.home1.oss.lib.security.api.Security;
import cn.home1.oss.lib.security.starter.PermitedRequestConfiguration;
import cn.home1.oss.lib.webmvc.api.TypeSafeCookie;
import cn.home1.oss.lib.webmvc.api.TypeSafeToken;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.env.Environment;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.web.filter.GenericFilterBean;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Not a bean, avoid auto pick-up.
* Created by zhanghaolun on 16/7/15.
*/
@Setter
@Getter(value = PROTECTED)
public class PreAuthTokenFilter extends GenericFilterBean {
public static final String ATTR_PRINCIPAL = "principal";
static final String ATTR_PRINCIPAL_TOKEN = "principal_token";
public static final String PERMITED = "PERMITED";
@Qualifier(GENERIC_USER_COOKIE)
@Autowired
private TypeSafeCookie<GenericUser> cookie;
@Qualifier(PermitedRequestConfiguration.PERMITED_REQUEST_MATCHER)
@Autowired(required = false)
private RequestMatcher permitedRequestMatcher;
@Qualifier(GENERIC_USER_TOKEN)
@Autowired
private TypeSafeToken<GenericUser> token;
@SuppressWarnings({"squid:S1871"})
@Override
public void doFilter( //
final ServletRequest req, //
final ServletResponse res, //
final FilterChain chain //
) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) req;
final HttpServletResponse response = (HttpServletResponse) res;
if (this.authenticationIsRequired()) {
final Object[] principalAndToken = this.findPrincipalAndToken(request);
final GenericUser principalFound = (GenericUser) principalAndToken[0];
final String tokenFound = (String) principalAndToken[1];
final GenericUser principal;
final String tokenContent;
if (principalFound != null && tokenFound != null) {
if (GenericUser.isGenericUserLogin(principalFound)) {
principal = principalFound;
tokenContent = tokenFound;
} else if (this.permitedRequestMatcher.matches(request)) { // unknown user
principal = null;
tokenContent = PERMITED;
} else {
// suppress sonar warnings about 'if structure with the same implementation is at best duplicate code'
principal = principalFound;
tokenContent = tokenFound;
}
} else if (this.permitedRequestMatcher.matches(request)) {
principal = null;
tokenContent = PERMITED;
} else {
principal = GenericUser.unknownUser();
tokenContent = this.token.toToken(principal);
// write unknownUser to client
response.setHeader(HEADER_AUTH_TOKEN, tokenContent);
this.cookie.setCookie(request, response, principal);
}
if (principal != null) {
request.setAttribute(ATTR_PRINCIPAL, principal);
}
if (tokenContent != null) {
request.setAttribute(ATTR_PRINCIPAL_TOKEN, tokenContent);
}
}
chain.doFilter(request, response);
}
Object[] findPrincipalAndToken(final HttpServletRequest request) {
// 自适应使用header或cookie.
final GenericUser principal;
final String tokenContent;
final String tokenFromHeader = request.getHeader(HEADER_AUTH_TOKEN);
final GenericUser principalFromHeader = this.token.fromToken(tokenFromHeader);
if (principalFromHeader != null) {
principal = principalFromHeader;
tokenContent = tokenFromHeader;
} else {
final String tokenFromCookie = this.cookie.getValue(request);
final GenericUser principalFromCookie = this.cookie.getCookie(request);
if (principalFromCookie != null) {
principal = principalFromCookie;
tokenContent = tokenFromCookie;
} else {
principal = null;
tokenContent = null;
}
}
return new Object[]{principal, tokenContent};
}
private boolean authenticationIsRequired() {
return Security.authenticationIsRequired();
}
@Autowired
@Override
public void setEnvironment(final Environment environment) {
super.setEnvironment(environment);
}
}