在 Spring Security Java Config 中创建多个 HTTP 部分

Posted

技术标签:

【中文标题】在 Spring Security Java Config 中创建多个 HTTP 部分【英文标题】:Creating multiple HTTP sections in Spring Security Java Config 【发布时间】:2013-09-19 20:03:04 【问题描述】:

使用 Spring Security XML 配置,您可以定义多个 HTTP 元素来为应用程序的不同部分指定不同的访问规则。 8.6 Advanced Namespace Configuration 中给出的示例定义了应用程序的独立有状态和无状态部分,前者使用会话和表单登录,后者使用无会话和 BASIC 身份验证:

<!-- Stateless RESTful service using Basic authentication -->
<http pattern="/restful/**" create-session="stateless">
    <intercept-url pattern='/**' access='ROLE_REMOTE' />
    <http-basic />
</http>

<!-- Empty filter chain for the login page -->
<http pattern="/login.htm*" security="none"/>

<!-- Additional filter chain for normal users, matching all other requests -->
<http>
    <intercept-url pattern='/**' access='ROLE_USER' />
    <form-login login-page='/login.htm' default-target-url="/home.htm"/>
    <logout />
</http>

我不知道如何用 Java Config 做同样的事情。禁用会话并为我的 Web 服务使用不同的入口点很重要。现在我有以下内容:

@Override
public void configure(WebSecurity security)

    security.ignoring().antMatchers("/resource/**", "/favicon.ico");


@Override
protected void configure(HttpSecurity security) throws Exception

    security
            .authorizeRequests()
                .anyRequest().authenticated()
            .and().formLogin()
                .loginPage("/login").failureUrl("/login?loginFailed")
                .defaultSuccessUrl("/ticket/list")
                .usernameParameter("username")
                .passwordParameter("password")
                .permitAll()
            .and().logout()
                .logoutUrl("/logout").logoutSuccessUrl("/login?loggedOut")
                .invalidateHttpSession(true).deleteCookies("JSESSIONID")
                .permitAll()
            .and().sessionManagement()
                .sessionFixation().changeSessionId()
                .maximumSessions(1).maxSessionsPreventsLogin(true)
                .sessionRegistry(this.sessionRegistryImpl())
            .and().and().csrf()
                .requireCsrfProtectionMatcher((r) -> 
                    String m = r.getMethod();
                    return !r.getServletPath().startsWith("/services/") &&
                            ("POST".equals(m) || "PUT".equals(m) ||
                                    "DELETE".equals(m) || "PATCH".equals(m));
                );

使用它,我能够为我的 Web 服务禁用 CSRF 保护。但我确实需要一个完整的单独 HTTP 配置,以便我可以禁用会话并指定不同的入口点。我知道我可以使用requestMatcherrequestMatchers 来限制它适用的URI,但您似乎不能使用它来创建单独的配置。这几乎就像我需要 两个 configure(HttpSecurity security) 方法。

【问题讨论】:

为安全配置创建多个类。最简单的方法是使用一些内部@Configuration 类创建一个通用配置,用于配置HttpSecurity 谢谢。这就是答案。此外,github.com/spring-projects/spring-security/blob/master/config/… 显示了使用静态内部类执行此操作的示例。您可以将您的评论放在答案中,以便我可以将其标记为答案并给予支持吗? 文档 (8.6 Advanced Namespace Configuration) 的 URL 引用已损坏。不是你可以在这里找到它docs.spring.io/spring-security/site/docs/3.2.5.RELEASE/… github 链接现在也坏了。 github.com/spring-projects/spring-security/blob/master/config/… 【参考方案1】:

在 Spring Security 中,为了模仿 Java 配置中 XML 中的多个 &lt;http&gt; 元素的行为,为安全配置创建多个类。一般来说,为HttpSecurity 的安全定义创建具有多个内部类 的通用安全配置是最好/最简单的。有关示例,请参阅 here。

这里是 Spring Security 官方文档中的相关部分:5.7 Multiple HttpSecurity

【讨论】:

我已经按照这里的示例进行了操作,但是由于第二个配置是全部捕获,因此所有 url 都被第二个配置拦截了。一旦我在第二个 httpsecurity 中输入了一个特定的 url(通过 antMatcher),所有的 url 都可以在没有身份验证的情况下访问。 这个答案的关键是每个安全配置类必须在第一个 antMatcher() 中标识一个唯一的 URL 路径。如:protected void configure(HttpSecurity http) http.antMatcher("/secure**") 旁边:protected void configure(HttpSecurity http) http.antMatcher("/api/**") issue 中代码的问题是这段代码匹配 ALL url:security.authorizeRequests() @informatik01 当我点击“这里”时,我得到 404。不知道是什么原因 @SandeepShukla 样本移动到 GitHub 中的另一个位置。我已经更新了指向当前位置的链接,它现在可用。

以上是关于在 Spring Security Java Config 中创建多个 HTTP 部分的主要内容,如果未能解决你的问题,请参考以下文章

Spring security在MS-SQL下的初始化脚本

Spring-security 的 CORS 问题

Spring Security 未创建 CSRF 令牌

java.security.Principal - 在 HttpServletRequest 和 Spring Security 中创建

尽管有 SecurityConfig,但 Spring Security 会阻止 POST 请求

我是这样使用SpringBoot(Spring Security实现用户登录)