【发布时间】:2014-01-29 08:22:31
【问题描述】:
我正在使用 Spring 4 创建 API,我需要对 API 请求进行身份验证。
目前,我创建了一个 HandlerInterceptorAdapter 来挑选与身份验证相关的标头并对这些值执行一些验证。
如果一切正常,我将 SecurityContext 设置为 Authentication 的自定义实现,然后在 postHandle 中将身份验证设置为 null。
一切都很好,除了我在 Tomcat7 中不断收到关于应用程序关闭时未删除 ThreadLocal 变量的警告。
SEVERE: The web application [] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@6c3e4fdb]) and a value of type [org.springframework.security.core.context.SecurityContextImpl] (value [org.springframework.security.core.context.SecurityContextImpl@ffffffff: Null authentication]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
我知道我可能做错了,如果是这样,我会喜欢一些方向。 :D
这是我的拦截器:
/**
* Intercepts Requests to set the Authentication in the SecurityContext.
* Sets the response to 401 - Unauthorized, if the header is missing
*/
@Component
public class AuthenticationHandlerInterceptor extends HandlerInterceptorAdapter {
private HandlerMediator mediator;
Logger log = LoggerFactory.getLogger(AuthenticationHandlerInterceptor.class);
@Autowired
public AuthenticationHandlerInterceptor(HandlerMediator mediator) {
this.mediator = mediator;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String username = request.getHeader("authentication-username");
String token = request.getHeader("authentication-token");
// if the remote host is local, then override the authentication
if (request.getRemoteHost().equals("0:0:0:0:0:0:0:1") || request.getRemoteHost().equals("127.0.0.1")) {
log.info("On localhost, overriding authentication with localhost");
username = "TEST";
token = "localhost:localhost";
}
if (username == null || username.trim().length() == 0) {
failAuthentication(response, "Missing Authentication Username Header");
return false;
}
if (token == null || token.trim().length() == 0 || !token.contains(":")) {
failAuthentication(response, "Missing Authentication Token Header");
return false;
}
String[] keys = token.split(":");
String appName = keys[0];
String apikey = keys[1];
if (!appName.equals("localhost")) {
// we are not under localhost so we have to authenticate the application calling us
if (mediator.executeCommand(new AuthenticateApplicationCommand(appName, apikey)) == false) {
failAuthentication(response, "Application Token failed authentication");
return false;
}
}
SecurityContextHolder.getContext().setAuthentication(new ApiAuthentication(username, appName));
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
SecurityContextHolder.getContext().setAuthentication(null);
}
private void failAuthentication(HttpServletResponse response, String message) throws Exception {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("text/html;charset=UTF-8");
ServletOutputStream out = response.getOutputStream();
out.println(message);
out.close();
}
}
如何消除这些警告?
谢谢, 乔
【问题讨论】:
标签: java spring authentication spring-mvc