【问题标题】:How does one use different session creation policies for UI and REST endpoints with Spring Security?如何使用 Spring Security 为 UI 和 REST 端点使用不同的会话创建策略?
【发布时间】:2022-01-25 15:38:47
【问题描述】:

我有一个包含 UI 和一些 REST 端点的应用程序。 UI 使用 SAML 登录(旧的 Spring Security SAML 扩展)和使用自定义身份验证的 REST 端点。 REST 端点仅由外部应用程序调用。 对于 REST 端点(“/api/**”),我已经声明了无状态会话创建策略,而对于端点的其余部分,则根本没有会话创建策略(我也尝试使用 ALWAYS,如下例所示)。

在某些 Spring Boot 版本之前,不确定是哪个版本,这有效。目前我正在使用 Spring Boot v.2.6.1。 UI 端点从 Http 会话中获取身份验证对象。

但现在它不起作用。在使用默认 HttpSessionSecurityContextRepository 实现的 Http 会话中找不到安全上下文对象。已保存但无法恢复。

那么是否可以使用两个会话创建策略,一个用于 REST,另一个用于 UI 部分,还是应该以不同的方式处理? 现在看来,UI 也使用了无状态会话创建策略,这不是有意的。 我正在使用两个 WebSecurityConfigurerAdapter 类;一个用于 API,另一个用于 UI。 成功登录 SAML 后,重定向 URL 现在包含“;jsessionid=6051854D94A0771BB9B99FE573AA4DFD”参数。可能是因为无国籍政策……?

    protected void configure(HttpSecurity http) throws Exception {

        List<AbstractAuthenticationProcessingFilter> authFilters = new ArrayList<>();
        authFilters.add(new OAuthMacAuthenticationProcessingFilter(authenticationManager(), this.properties));

        ApiAuthenticationProcessingFilter apiAuthenticationProcessingFilter = new ApiAuthenticationProcessingFilter(authenticationManager(),authFilters);

        http
        .csrf()
        .disable()
        .antMatcher("/api/**")
        .authorizeRequests()
        .anyRequest()
        .authenticated()
        .and()
        .exceptionHandling()
        .authenticationEntryPoint((req, rsp, e) -> rsp.sendError(HttpServletResponse.SC_UNAUTHORIZED))
        .and()
        .addFilterBefore(apiAuthenticationProcessingFilter, BasicAuthenticationFilter.class)
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

对于 UI 部分

    protected void configure(HttpSecurity http) throws Exception {

        http.securityContext().securityContextRepository(customSessionSecurityContextRepository);

        http
        .httpBasic()
        .authenticationEntryPoint(samlEntryPoint());

        http
        .addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class);

        var auth = http
                .authorizeRequests()
                .antMatchers("/saml/**").permitAll()
                .antMatchers("/loggedout/**").permitAll()
                .antMatchers("/error").permitAll();
                
        auth
        .anyRequest()
        .authenticated();

        http.csrf().disable();

        http.sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.ALWAYS);

        http.headers().frameOptions().sameOrigin();

        http.exceptionHandling().accessDeniedHandler(this.accessDeniedHandler());

        http
        .logout()
        .disable();    // The logout procedure is already handled by SAML filters.
    }

【问题讨论】:

    标签: spring-boot spring-security


    【解决方案1】:

    我会自己回答这个问题。上面的代码确实有效。问题出在远程端,那天我使用的 IDP 出现了一些问题,导致它没有按预期工作。第二天,它奏效了。

    【讨论】:

      猜你喜欢
      • 2020-02-22
      • 2020-11-25
      • 1970-01-01
      • 2016-03-04
      • 2019-06-19
      • 2018-11-21
      • 2017-09-17
      • 2014-11-03
      • 2019-05-08
      相关资源
      最近更新 更多