【问题标题】:Spring-boot-oauth2-angularjs, error with CORS after session expiry and redirect to oauth2 serverSpring-boot-oauth2-angularjs,会话到期后CORS出错并重定向到oauth2服务器
【发布时间】:2016-07-23 22:26:17
【问题描述】:

我有一个前端应用程序,它在服务器端使用 Spring-boot、Spring security oauth2,在客户端使用 AngularJs。我还使用第三方 oauth2 服务器。我的问题是,在应用程序会话到期后,sping-security 将所有请求重定向到“/login”(这正是它应该是的),并且我得到了 302 状态代码,其中包含在响应头中的 auth-server 页面上重定向的位置.但是重定向没有发生,因为我收到错误:

XMLHttpRequest 无法加载 ****://bla-bla/oauth/authorize?client_id=...andSomeAuthStuff。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,Origin '****://myipadress:8084' 不允许访问。

问题是为什么第一次进入应用程序或刷新页面或注销和新登录不涉及这样的错误并且一切顺利但只有当我得到会话超时时(例如我从死视图发出 ajax 请求), 发生 CORS 错误:-(

我重现了这些步骤:

  1. 在“死”页面上,我向我的 API 发出 ajax 请求(Spring-boot 1.3.3 WAR 在提供的 Tomcat 8 上运行)
  2. Spring 拦截请求并响应:

一般:

请求网址:***//myipadress:8084/appname/login

请求方法:GET

找到状态码:302

远程地址:myipadress:8084

响应标头:

Access-Control-Allow-Headers:授权、Content-Type、Accept、x-requested-with、Cache-Control

访问控制允许方法:POST、GET、OPTIONS、DELETE、PUT

访问控制允许来源:*

访问控制最大年龄:3600

Cache-Control:no-cache, no-store, max-age=0, must-revalidate

位置:*//authserver/oauth/authorize?client_id=******&redirect_uri=*://myipadress:8084/appname/login&response_type=code&state=BIQ68y

Pragma:no-cache

服务器:Apache-Coyote/1.1

设置 Cookie:JSESSIONID=05D39263EEF7EC9E24AEE8E1E6693748;路径=/appname/; HttpOnly

X-Content-Type-Options:nosniff

X-Frame-Options:拒绝

X-XSS-保护:1;模式=块

CORS 过滤器:

public class SimpleCORSFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse) response;
        res.setHeader("Access-Control-Allow-Origin", "*");
        res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        res.setHeader("Access-Control-Max-Age", "3600");
        res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, x-requested-with, Cache-Control");
        chain.doFilter(request, res);
    }

    @Override
    public void destroy() {
    }
}

安全配置:

@EnableOAuth2Sso
@Configuration
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.logout()
                .and().antMatcher("/**")
                .authorizeRequests()
                .anyRequest().authenticated()
                .and().csrf().disable()
                .addFilterBefore(new SimpleCORSFilter(), ChannelProcessingFilter.class);
    }

}

ajax 请求后的日志:

2016-04-04 14:10:42.613 DEBUG 5428 --- [o-8084-exec-144] o.s.s.w.u.matcher.AntPathRequestMatcher:检查请求的匹配:'/login';反对“/登录” 2016-04-04 14:10:42.613 调试 5428 --- [o-8084-exec-144] uth2ClientAuthenticationProcessingFilter:请求是处理身份验证 2016-04-04 14:10:42.615 调试 5428 --- [o-8084-exec-144] w.c.HttpSessionSecurityContextRepository:SecurityContext 为空或内容是匿名的 - 上下文不会存储在 HttpSession 中。 2016-04-04 14:10:42.657 调试 5428 --- [o-8084-exec-144] s.s.w.c.SecurityContextPersistenceFilter:SecurityContextHolder 现在已清除,因为请求处理已完成 2016-04-04 14:10:42.658 调试 5428 --- [o-8084-exec-144] ossweb.DefaultRedirectStrategy:重定向到 '****://authserver/oauth/authorize?client_id=*** **&redirect_uri=***://myipadress:8084/appname/login&response_type=code&state=iNdnBk'

【问题讨论】:

    标签: angularjs ajax spring spring-mvc oauth


    【解决方案1】:

    我认为您需要将 @EnableWebSecurity 注释添加到您的 CustomWebSecurityConfigurerAdapter。

    【讨论】:

    • 我钩了这个注释,但问题仍然存在。我发现了几个与我类似的案例,并且所有问题都在 302 重定向下作为响应。不幸的是,所有解决方案都不能解决问题
    【解决方案2】:

    另外,我试着换一种方式,把过滤器放在这样的地方:

     @Override
        public void configure(HttpSecurity http) throws Exception {
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            CorsConfiguration config = new CorsConfiguration();
            config.setAllowCredentials(true); 
            config.addAllowedOrigin("*");
            config.addAllowedHeader("*");
            config.addAllowedMethod("GET");
            config.addAllowedMethod("PUT");
            source.registerCorsConfiguration("/**", config);
            CorsFilter filter = new CorsFilter(source);
    
            http
                    .logout()
                    .and().antMatcher("/**")
                    .authorizeRequests()
                    .anyRequest().authenticated()
                    .and().csrf().disable()
                    .addFilterBefore(filter, ChannelProcessingFilter.class);
        }
    

    但它也没有帮助,响应的 CORS 标头都消失了!

    【讨论】:

      【解决方案3】:

      我认为原因不在标题中,而是在响应中的状态码 302 中。我如何来到 401 而不是 302?

      【讨论】:

        猜你喜欢
        • 2020-04-15
        • 1970-01-01
        • 1970-01-01
        • 2017-05-13
        • 2015-07-17
        • 1970-01-01
        • 2016-02-28
        • 2017-12-27
        相关资源
        最近更新 更多