【问题标题】:Access REST API protected with Spring Security访问受 Spring Security 保护的 REST API
【发布时间】:2015-03-21 07:01:52
【问题描述】:

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

【问题讨论】:

  • 你也试过浏览器吗?我猜它无法维持会话。
  • @PramodKarandikar 我不想让它在浏览器中可用。我需要客户端通过基于 JavaScript 的框架或类似的东西来访问这个 REST API。是的,你是对的,它无法维持会话。

标签: spring rest spring-security


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2014-02-21
    • 2013-01-26
    • 2014-12-06
    • 2019-01-14
    • 2021-11-09
    • 2014-07-29
    • 2018-08-11
    • 2015-12-09
    • 2013-11-29
    相关资源
    最近更新 更多