我正在尝试创建一个主要使用 Spring 提供 REST API 的 Web 应用程序,并尝试配置安全方面。
我正在尝试实现这种模式:https://developers.google.com/accounts/docs/MobileApps https://developers.google.com/accounts/docs/MobileApps(谷歌已经完全改变了该页面,所以不再有意义 - 请参阅我在这里提到的页面:http://web.archive.org/web/20130822184827/https://developers.google.com/accounts/docs/MobileApps http://web.archive.org/web/20130822184827/https://developers.google.com/accounts/docs/MobileApps)
这是我需要完成的任务:
- Web应用程序具有简单的登录/注册表单,可以与普通的spring用户/密码身份验证一起使用(之前已经使用dao/authenticationmanager/userdetailsservice等完成了此类操作)
- REST api 端点是无状态会话,每个请求都根据请求提供的令牌进行身份验证
(例如,用户使用普通表单登录/注册,webapp 提供带有令牌的安全 cookie,然后可以在以下 API 请求中使用该令牌)
我有一个正常的身份验证设置,如下所示:
@Override protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.antMatchers("/mobile/app/sign-up").permitAll()
.antMatchers("/v1/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/")
.loginProcessingUrl("/loginprocess")
.failureUrl("/?loginFailure=true")
.permitAll();
}
我正在考虑添加一个预身份验证过滤器,该过滤器检查请求中的令牌,然后设置安全上下文(这是否意味着将跳过正常的后续身份验证?),但是,超出了我所拥有的正常用户/密码没有对基于令牌的安全性做太多事情,但根据其他一些示例,我提出了以下内容:
安全配置:
@Override protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.addFilter(restAuthenticationFilter())
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.exceptionHandling().authenticationEntryPoint(new Http403ForbiddenEntryPoint()).and()
.antMatcher("/v1/**")
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.antMatchers("/mobile/app/sign-up").permitAll()
.antMatchers("/v1/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/")
.loginProcessingUrl("/loginprocess")
.failureUrl("/?loginFailure=true")
.permitAll();
}
我的自定义休息过滤器:
public class RestAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public RestAuthenticationFilter(String defaultFilterProcessesUrl) {
super(defaultFilterProcessesUrl);
}
private final String HEADER_SECURITY_TOKEN = "X-Token";
private String token = "";
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
this.token = request.getHeader(HEADER_SECURITY_TOKEN);
//If we have already applied this filter - not sure how that would happen? - then just continue chain
if (request.getAttribute(FILTER_APPLIED) != null) {
chain.doFilter(request, response);
return;
}
//Now mark request as completing this filter
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
//Attempt to authenticate
Authentication authResult;
authResult = attemptAuthentication(request, response);
if (authResult == null) {
unsuccessfulAuthentication(request, response, new LockedException("Forbidden"));
} else {
successfulAuthentication(request, response, chain, authResult);
}
}
/**
* Attempt to authenticate request - basically just pass over to another method to authenticate request headers
*/
@Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
AbstractAuthenticationToken userAuthenticationToken = authUserByToken();
if(userAuthenticationToken == null) throw new AuthenticationServiceException(MessageFormat.format("Error | {0}", "Bad Token"));
return userAuthenticationToken;
}
/**
* authenticate the user based on token, mobile app secret & user agent
* @return
*/
private AbstractAuthenticationToken authUserByToken() {
AbstractAuthenticationToken authToken = null;
try {
// TODO - just return null - always fail auth just to test spring setup ok
return null;
} catch (Exception e) {
logger.error("Authenticate user by token error: ", e);
}
return authToken;
}
上面的内容实际上会导致应用程序启动时出现错误:authenticationManager must be specified
谁能告诉我如何最好地做到这一点 - pre_auth 过滤器是做到这一点的最佳方法吗?
EDIT
我写下了我的发现以及如何使用 Spring-security(包括代码)实现标准令牌实现(不是 OAuth)
问题和方法/解决方案概述 https://automateddeveloper.blogspot.co.uk/2014/03/securing-your-api-for-mobile-access.html
使用 Spring-security 实施解决方案 https://automateddeveloper.blogspot.co.uk/2014/03/securing-your-mobile-api-spring-security.html
希望它能帮助其他一些人..