弹簧安全/注销无法跨越原始请求

时间:2016-07-19 13:29:37

标签: angularjs spring spring-security spring-boot

我的AngularJS应用程序有一个登录和注销按钮。 登录按钮工作正常,以及发送到我后端的所有其他请求。

尝试注销时出现问题。

我收到了以下错误。

XMLHttpRequest cannot load http://localhost:8081/logout. The request was redirected to 'http://localhost:8081/login?logout', which is disallowed for cross-origin requests that require preflight.

这是我的代码:

'use strict';
angular.module('emifEkolFinderApp').controller('logoutController', ['$scope', 'CONFIGURATION', 'AccessToken', '$http', '$location', function ($scope, CONFIGURATION, AccessToken, $http, $location) {
    $scope.logout = function () {
        var userUrl = 'http://' + CONFIGURATION.OAUTH_SERVER_IP_AND_PORT + '/logout';
        var data = AccessToken.set().access_token;
        $http.post(userUrl,JSON.stringify("{}")).then(function (successCallback) {
            AccessToken.destroy();
            console.log("Revokin'");
            $location.path("/");
        }, function (errorCallback) {
            console.log(errorCallback);
        });
    };
}]);

Spring安全配置:

@Configuration
public class ServerSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    protected void configure(final AuthenticationManagerBuilder auth)
            throws Exception {
        auth.parentAuthenticationManager(authenticationManager).userDetailsService(userDetailsService);
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .antMatchers("/resources/**").permitAll()
            .antMatchers("/login").permitAll()
            .antMatchers("/logout").permitAll()
            .anyRequest().authenticated()
            .and()
            .csrf().disable()
            .formLogin()
            .loginPage("/login").permitAll()
            .and()
            .httpBasic()
            .and()
            .logout()
            .permitAll()
            .deleteCookies("JSESSIONID")
            .invalidateHttpSession(true);
}

}

我的CORS过滤器:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, HEAD");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization,  cache-control, content-type, Origin, key");
        response.setHeader("Content-Type", "*");
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            filterChain.doFilter(request, response);
        }
    }
}

我真的在黑暗中感动。非常感谢帮助。

2 个答案:

答案 0 :(得分:2)

我认为您的问题与注销后的重定向有关,请尝试通过实现LogoutSuccessHandler关闭此重定向,如下问题: Spring security - Disable logout redirect

http.logout().logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler (HttpStatus.OK)));

答案 1 :(得分:0)

Spring注销登录的默认行为是,在成功注销后,它会将请求重定向到默认为default logout succes url的{​​{1}}。

这是重定向操作,但不允许使用rest调用重定向。因此您的注销代码会中断。您需要添加一个自定义注销处理程序,该处理程序不会将您重定向到另一个路径。

如何做到这一点。创建一个自定义Logout处理程序并从那里发送响应,如

/login?logout