【发布时间】:2014-09-12 17:09:53
【问题描述】:
我有使用 spring+hibernate+rest 构建的后端服务,每个 rest 服务 url 都接受 Json 作为输入并将 json 作为对 forntend(web,Android,Ios) 的响应,登录后我们向前端发送一个唯一的随机数,为了访问/调用他使用这个唯一号码的进一步服务,现在我想实现弹簧安全,我想实现基于令牌的唯一随机数的通信......任何解决方案?我还需要启动示例代码?
【问题讨论】:
我有使用 spring+hibernate+rest 构建的后端服务,每个 rest 服务 url 都接受 Json 作为输入并将 json 作为对 forntend(web,Android,Ios) 的响应,登录后我们向前端发送一个唯一的随机数,为了访问/调用他使用这个唯一号码的进一步服务,现在我想实现弹簧安全,我想实现基于令牌的唯一随机数的通信......任何解决方案?我还需要启动示例代码?
【问题讨论】:
不幸的是,Spring security 没有开箱即用的令牌安全实现。您会在以下帖子中找到一些线索:
我必须自己实现它,这并不是那么简单......显而易见的部分是你需要一个过滤器。我的要求是令牌具有时间限制的有效性,并且即使应用程序部署在多个服务器上(冗余)也可以使用,因此我将令牌存储在数据库中。我结束了:
使用以下doFilter 方法将TokenAuthenticationFilter 定位为PRE_AUTH_FILTER:
@Override
public void doFilter(ServletRequest sr, ServletResponse sr1, FilterChain fc) throws IOException, ServletException {
boolean tokenAuthenticated = false;
HttpServletRequest request = (HttpServletRequest) sr;
String token = findToken(request);
if ((null == token) || (!authenticationNeeded(request))) {
fc.doFilter(sr, sr1);
return;
}
if (needHttps && (! request.isSecure())) {
TokenAuthenticationToken at = new TokenAuthenticationToken(token);
try {
at.setDetails(detailsSource.buildDetails(request));
Authentication auth = manager.authenticate(at);
if ((auth != null) && (auth.isAuthenticated())) {
SecurityContextHolder.getContext().setAuthentication(auth);
tokenAuthenticated = true;
}
} catch (AuthenticationException e) {
logger.debug("Authentication failed :", e);
}
}
else {
logger.info("Token identification rejected : proto != https");
}
fc.doFilter(sr, sr1);
if (tokenAuthenticated) {
logger.debug("Token authenticated : invalidate session");
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
}
}
一个JdbcTokenAuthenticationProvider(使用前一个过滤器设置的TokenAuthenticationToken)将过滤器部分与真正的身份验证部分分开(并坚持常见的AuthenticationManager用法)
JdbcTokenAuthenticationManager 做 DAO 部分,包括令牌创建和数据库清理希望对你有帮助...
【讨论】: