这是我的配置(使用Spring Security 3.2.5):
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationEntryPoint entryPoint;
@Autowired
private UsernamePasswordAuthenticationFilter userPassAuthFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic()
.authenticationEntryPoint(entryPoint);
http.addFilterAfter(userPassAuthFilter, UsernamePasswordAuthenticationFilter.class)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
这是我的bean配置:
@Bean
public AuthenticationManager authenticationManager() {
List providers = new LinkedList();
providers.add(daoAuthenticationProvider());
ProviderManager pm = new ProviderManager(providers);
return pm;
}
@Bean
public AuthenticationEntryPoint entryPoint() {
return new MyAuthenticationEntryPoint();
}
@Bean
public UsernamePasswordAuthenticationFilter restApiAuthenticationFilter() {
MyAuthFilter filter = new MyAuthFilter();
filter.setAuthenticationManager(authenticationManager());
filter.setUsernameParameter("username");
filter.setPasswordParameter("password");
filter.setAuthenticationSuccessHandler(authenticationSuccessHandler());
filter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/**"));
return filter;
}
@Bean
public AuthenticationSuccessHandler authenticationSuccessHandler() {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setUseReferer(true);
return successHandler;
}
MyAuthFilter如下:
public class MyAuthFilter extends UsernamePasswordAuthenticationFilter {
@Transactional
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
//do my job here related to setting some custom header on request.
super.successfulAuthentication(request, response, chain, authResult);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
//check for my header and authenticate if this is the case, otherwise, call super.
return super.attemptAuthentication(request, response);
}
}
和MyAuthenticationEntryPoint如下:
public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, org.springframework.security.core.AuthenticationException authException) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
现在,问题是,当我访问我手上的其他api时,我得到如下:
curl -i -H "auth_header: a_token_value_here" http://myhost:8080/path/api/list_users
我明白了:
HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
auth_header: a_token_value_here
Location: http://myhost:8080/path/
Content-Length: 0
Date: Thu, 22 Jan 2015 13:01:24 GMT
正如您所看到的,由于Spring不允许我到达那里,我无法访问所请求的REST API。在Spring检查我已经过身份验证之后,它只是停止重定向我,而是发送重定向状态响应,如果我访问,我会再次获得相同的响应。 有人可以使用这种方法指导我如何通过Spring Security获得REST API吗?
答案 0 :(得分:2)
你的代码有点乱,但这里有一些指示:
.httpBasic()
。您是否使用HTTP Basic作为身份验证方法?如果没有,请删除。UsernamePasswordAuthenticationFilter
。这适用于Web浏览器表单身份验证。也许你想用AbstractAuthenticationProcessingFilter
作为超类。SavedRequestAwareAuthenticationSuccessHandler
用于基于会话的有状态登录。这可能会导致重定向。删除。