Spring security + session:接收“Set-Cookie”标头但未在浏览器中设置

Posted

技术标签:

【中文标题】Spring security + session:接收“Set-Cookie”标头但未在浏览器中设置【英文标题】:Spring security + session : Receive "Set-Cookie" header but not set in browser 【发布时间】:2019-11-12 00:58:01 【问题描述】:

我正在尝试使用 Angular 前端的 Spring Security & Session。 尝试使用该响应标头登录时收到 200 代码:

Set-Cookie: SESSION=NGJlYTkzODQtNTQzMy00NGIxLWEzOWYtYTc2MGNlZWY1OTJm; Path=/; HttpOnly; SameSite=Lax

但是在我对服务器的下一个请求中,请求中没有自动设置cookie。顺便说一句,我在开发者工具中看不到 cookie,所以我认为它没有保存。

我在本地工作,负责前端和后端。

这里有一些关于后端的信息:

使用 Spring MongoDb 会话 @Configuration @EnableMongoHttpSession public class SessionConfig

经典 Spring 安全配置

` @EnableWebSecurity 公共类 SecurityConfig 扩展 WebSecurityConfigurerAdapter private final CustomAuthenticationProvider authProvider;

public SecurityConfig(CustomAuthenticationProvider authProvider) 
    this.authProvider = authProvider;


@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception 
    auth.authenticationProvider(authProvider);


@Override
protected void configure(HttpSecurity http) throws Exception 
    http
        .cors().and()
        .authorizeRequests()
        .anyRequest().authenticated()
        .and()
        .httpBasic(); //todo csrf


@Bean
CorsConfigurationSource corsConfigurationSource() 
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Collections.singletonList("http://localhost:4200")); // todo properties by environment
    configuration.setAllowedMethods(Arrays.asList("GET", "POST", "OPTIONS", "DELETE", "PUT", "PATCH"));
    configuration.setAllowedHeaders(Arrays.asList("X-Requested-With", "Origin", "Content-Type", "Accept", "Authorization"));
    configuration.setAllowCredentials(true);
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;

`

会话很好地保存在mongodb中,只是id没有保存在浏览器中。 有什么想法吗?

编辑

在 httpClient 参数中设置observer: "response" 时,我看不到 Set-Cookie 标头:

"cache-control: no-cache, no-store, max-age=0, must-revalidate,content-type: application/json,expires: 0,pragma: no-cache"

但是在我的开发者工具中:

HTTP/1.1 200 Vary: Origin Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Access-Control-Allow-Origin: http://localhost:4200 Access-Control-Allow-Credentials: true 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 Set-Cookie: SESSION=YTEwOTNkNjAtZjI4MS00ZmM2LWExYmEtYzA5NzJhMjAyNTJh; Path=/; HttpOnly; SameSite=Lax Content-Type: application/json Transfer-Encoding: chunked Date: Mon, 01 Jul 2019 11:25:08 GMT

【问题讨论】:

尝试通过传递选项来读取角度侧的完整响应:'response' Set-Cookie 不在数组中。我只有"cache-control: no-cache, no-store, max-age=0, must-revalidate,content-type: application/json,expires: 0,pragma: no-cache" 明白了!谢谢@Mrcode。我不得不在角度边添加 withCredentials 参数。 【参考方案1】:

问题出在角度方面! 我添加了一个拦截器,添加了 withCredentials 参数,它可以工作。

@Injectable()
export class XhrInterceptor implements HttpInterceptor 

  intercept(req: HttpRequest<any>, next: HttpHandler) 
    const xhr = req.clone(
      withCredentials: true
    );
    return next.handle(xhr);
  

【讨论】:

【参考方案2】:

在后端创建一个 CORS 过滤器添加这个

response.setHeader("Access-Control-Allow-Headers",
                "Date, Content-Type, Accept, X-Requested-With, Authorization, From, X-Auth-Token, Request-Id");
response.setHeader("Access-Control-Expose-Headers", "Set-Cookie");
response.setHeader("Access-Control-Allow-Credentials", "true");

【讨论】:

以上是关于Spring security + session:接收“Set-Cookie”标头但未在浏览器中设置的主要内容,如果未能解决你的问题,请参考以下文章

Spring Session 和 Spring Security

spring security控制session

spring session 和 spring security整合

Spring Security 梳理 - session

Spring Security(13)——session管理

Spring Security教程之session管理