我正在尝试按this guide
的方式实现API基本流程是:
所以我试图通过登录表单来保护我的webapp以允许正常的登录流程(使用Spring Security),然后根据请求头中传递的令牌对所有对/ api / **的请求进行身份验证。
我最初通过两个网络配置开始实现这一点 - 一个用于正常的webapp安全性:
@Override protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.antMatchers("/sign-in").permitAll()
.antMatchers("/success").authenticated()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/")
.loginProcessingUrl("/loginprocess")
.failureUrl("/sign-in?loginFailure=true")
.permitAll();
}
上面只定义了标准的spring安全认证(自定义userDetailsService以从DB获取用户详细信息)并验证登录和成功页面。
然后另一个(两个文件只是为了清晰/易于阅读)进行API身份验证:
@Override protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**")
.csrf()
.disable()
.authorizeRequests().anyRequest().authenticated().and()
.addFilterBefore(authenticationTokenFilter(), BasicAuthenticationFilter.class )
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.exceptionHandling().authenticationEntryPoint(new Http403ForbiddenEntryPoint());
}
上面有一个pre-auth过滤器,它从请求中获取相关的HTTP头(令牌等)并将它们添加到安全上下文中 - 然后自定义身份验证提供程序验证令牌/用户详细信息。
一切都很好 - 然而,感觉我正在重新发明一堆东西。看过Spring Security的RememberMe功能后,看起来他们已经处理了很多这样的事情 - 在登录时它返回一个带有令牌的cookie,然后可以用于在将来的请求中自动登录。来自the java docs:
<bean id="rememberMeFilter" class=
"org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<property name="rememberMeServices" ref="rememberMeServices"/>
<property name="authenticationManager" ref="theAuthenticationManager" />
</bean>
<bean id="rememberMeServices" class=
"org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="myUserDetailsService"/>
<property name="key" value="springRocks"/>
</bean>
<bean id="rememberMeAuthenticationProvider" class=
"org.springframework.security.authentication.rememberme.RememberMeAuthenticationProvider">
<property name="key" value="springRocks"/>
</bean>
唯一的问题是我希望将令牌作为标题参数包含在将来的请求中,而不是cookie。我查看了上述类的源代码,并且TokenBasedRememberMeServices类autoLogin()
方法显式检查了cookie。该代码还使用MD5作为散列的默认值。
我的问题是:
我宁愿不必扩展所有这些类,因为一堆核心内容是相同的,并且只是为了更改令牌源和散列算法而扩展它们似乎有些过分。
答案 0 :(得分:7)
好的,看了一下,似乎没有为请求标头实现RememberMe功能的核心类 - 但是,阅读Spring Security记住我的源代码,实际上很容易将上面的类扩展到查看请求标题。
详细信息都在这里:http://automateddeveloper.blogspot.co.uk/2014/03/securing-your-mobile-api-spring-security.html但基本上只是正常使用RememberMe,但是然后扩展TokenBasedRememberMeServices并覆盖extractCookie方法,只是从标题而不是cookie中抓取令牌(可能有点hacky,扩展一个名为extractCookie的方法来获取请求标题,但它可以工作)