执行跨域请求时的Spring drop session

时间:2015-10-23 16:21:48

标签: spring spring-mvc session

我正在尝试创建一个javascript应用程序,只通过其余接口(@RestController)与spring(spring-boot)编写的后端进行通信。问题是请求是跨域的,最后在用户登录应用程序后似乎没有建立会话。当我尝试向后端发送新的http请求时,登录后,Principal为空。

这是我的安全配置:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/**").permitAll()
                .and()
                .formLogin()
                    .passwordParameter("password")
                    .usernameParameter("email")
                    .loginPage("/")
                    .failureHandler(new JsonAuthenticationFailureHandler())
                    .successHandler(new JsonAuthenticationSuccessHandler())
                .and()
                .rememberMe()
                .and()
                .logout()
                    .deleteCookies("remember-me")
                    .logoutSuccessUrl("/")
                    .logoutUrl("/logout")
                .and()
                .csrf()
                    .disable();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth, PasswordEncoder encoder) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(encoder);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        PasswordEncoder encoder = new BCryptPasswordEncoder();
        return encoder;
    }
}

这是我的CORS配置:

@Component
public class SimpleCORSFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {}

    public void destroy() {}

}

我成功登录后尝试调用的示例控制器:

@RestController
@RequestMapping("/rest/users")
public class UserController extends AbstractRestController {

    @Autowired
    private UserService userService;

    /**
     * Exposed public method for registering the user
     *
     * @param email    email to log in
     * @param password password to log in
     * @return BooleanResponse.result == true if the user registration succeeded without any problems
     */
    @RequestMapping(value = "/register", method = {RequestMethod.POST, RequestMethod.GET})
    public RegistrationResponse register(@RequestParam String email, @RequestParam String password) {
        try {
            userService.createUser(email, password);
        } catch (UserRegistrationException e) {
            return new RegistrationResponse(e.getErrors());
        }
        return new RegistrationResponse(Arrays.asList(RegistrationStatus.SUCCESS));
    }

    /**
     * Determines whether a user with a specific email address already exists
     *
     * @param email email address to be searched for
     * @return BooleanResponse.result = true if the user with the specific email already exists
     */
    @RequestMapping(value = "/userExists", method = {RequestMethod.POST, RequestMethod.GET})
    public BooleanResponse userExists(@RequestParam String email) {
        boolean response = userService.userWithEmailExists(email);
        return new BooleanResponse(response);
    }

    /**
     * Searches for the user info
     *
     * @param principal uniquely identifying the logged in user
     * @return user info for the user with the specified email address
     */
    @RequestMapping(value = "/userInfo", method = RequestMethod.GET)
    public UserInfo getUserInfo(Principal principal) {
        return userService.findUserInfo(principal.getName());
    }


    /**
     * Update info of the currently logged in user
     *
     * @param userInfo new user info provided in the request body
     */
    @RequestMapping(value = "/userInfo", method = RequestMethod.POST)
    public void submitUserInfo(@RequestBody UserInfo userInfo, Principal principal) {
        userService.updateUserInfo(principal.getName(), userInfo);
    }
}

因此,如果用户已登录,则submitUserInfo和getUserInfo应接收Principal对象,但他们不会。我还尝试在JsonAuthenticationSuccessHandler中添加会话属性,但是当我将相应的@SessionAttributes添加到我的控制器并尝试使用@ModelAttribute获取方法内的属性时,我仍然无法得到它,因此假设我的http会话不正确建立的。

1 个答案:

答案 0 :(得分:0)

不确定如何在JS中进行AJAX调用。

如果您使用的是AngularJS,则需要在执行AJAX调用时添加凭据,

$http({
                    method: 'PUT',
                    url: <rest_api>,
                    withCredentials: true,
                    data: {},
                })..then(function successCallback(response) {