这是我的配置(使用 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 吗?
最佳答案
您的代码有点困惑,但这里有一些提示:
- 您的配置中有
.httpBasic()
。您使用 HTTP Basic 作为身份验证方法吗?如果没有,请删除。 - 您的身份验证过滤器基于
UsernamePasswordAuthenticationFilter
。这是用于 Web 浏览器表单例份验证。也许您想使用AbstractAuthenticationProcessingFilter
作为父类(super class)。 SavedRequestAwareAuthenticationSuccessHandler
用于有状态、基于 session 的登录。这很可能会导致重定向。删除。
关于spring - 访问受 Spring Security 保护的 REST API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28089589/