访问受Spring Security保护的REST API

时间:2015-01-22 13:07:53

标签: spring rest spring-security

这是我的配置(使用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吗?

1 个答案:

答案 0 :(得分:2)

你的代码有点乱,但这里有一些指示:

  1. 您的配置中有.httpBasic()。您是否使用HTTP Basic作为身份验证方法?如果没有,请删除。
  2. 您的身份验证过滤器基于UsernamePasswordAuthenticationFilter。这适用于Web浏览器表单身份验证。也许你想用AbstractAuthenticationProcessingFilter作为超类。
  3. SavedRequestAwareAuthenticationSuccessHandler用于基于会话的有状态登录。这可能会导致重定向。删除。