Spring Security 当Angular应用程序在开发中运行时,Spring安全会话不工作(ng serve)

vc6uscn9  于 2023-04-21  发布在  Spring
关注(0)|答案(1)|浏览(142)

正如标题所暗示的,我使用Spring/Spring Security开发了后端,前端是一个Angular应用程序。
当我使用ng serve(http://localhost:4200)启动angular app时,spring session不工作。当我请求从后端(http://localhost:8080)提供应用程序时,spring session按预期工作。

最相关的spring安全配置

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        .httpBasic()
        .and()
        .logout().clearAuthentication(true).invalidateHttpSession(true).deleteCookies("JSESSIONID")
        .and()
        .rememberMe().key("uniqueAndSecret").rememberMeParameter("rememberMe").tokenValiditySeconds(Integer.parseInt(rememberMeDuration))
        .and()
        .authorizeHttpRequests().antMatchers(UNPROTECTED_ROUTES).permitAll().anyRequest().authenticated()
        .and()
        .csrf().disable()
        .cors().configurationSource(corsConfigurationSource())
        .and()
        .authenticationManager(authManager(http, userDetailsServiceConfig))
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS);
    return http.build();
}

@Bean
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();

    configuration.setAllowCredentials(true);
    configuration.setAllowedMethods(Arrays.asList(HttpMethod.GET.name(), HttpMethod.HEAD.name(), HttpMethod.POST.name(), HttpMethod.OPTIONS.name()));
    configuration.setAllowedHeaders(Collections.singletonList("*"));
    configuration.setExposedHeaders(Collections.singletonList("*"));
    configuration.setAllowedOrigins(Collections.singletonList("http://localhost:4200"));

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration(
            "/**",
            new CorsConfiguration().applyPermitDefaultValues().combine( configuration)
    );
    return source;
}

还有一个来自前端的请求不起作用的例子(当从ng serve运行时)。我总是得到401(当我调用此代码时,我已经成功进行了身份验证)

public vehicleAlimentationByCSV(formData: FormData): Observable<VehicleAlimentationResponseModel> {
    const endPoint = `${this.url}/csv`;

    return this.http
        .post<VehicleAlimentationResponseModel>(
            endPoint,
            formData,
            {
                observe: 'response',
                withCredentials: true
            }
        )
        .pipe(
            map(resp => resp.body!)
        );
}

也许是一个非常简单的错过配置。我已经搜索了为什么会发生这种情况的解释,但我什么也没有得到。
谢谢你的时间!

t3psigkw

t3psigkw1#

我有点晚了,但总比不来好...
当在端口4200上运行时,在开发模式下,为了使cookie JSESSIONID正常工作,我们只需要添加'withCredential:请求选项为true:

public login(email: string, password: string, rememberMe: boolean): Observable<UserModel> {
    let basicAuth = btoa(`${email}:${password}`);

    const headers = new HttpHeaders({
        'Authorization': `Basic ${basicAuth}`
    });

    this.loadingService.startLoading();

    return this.http
        .post<UserModel>(`${this.domainUrl}login?rememberMe=${rememberMe}`, {}, {headers: headers, observe: 'response', withCredentials: true})
        .pipe(
            map(resp => new UserModel(resp.body!.email, resp.body!.role)),
            tap(user => {
                this.user.next(user);
                this.loadingService.stopLoading();
            }),
            catchError(err => {
                this.loadingService.stopLoading();
                throw err;
            })
        );
}

相关问题