【问题标题】:Exclude certain URL patterns from Spring Security从 Spring Security 中排除某些 URL 模式
【发布时间】:2022-10-19 17:14:52
【问题描述】:

我在我的 Struts 应用程序中使用 Spring Security 4,并希望所有 URL 都通过 Spring Security,但以 /rest 开头的 URL 除外。我怎样才能让它工作,因为我知道在 web.xml 中不允许使用正则表达式模式。

因此,<url-pattern>^(?!\/rest).*$</url-pattern> 不起作用。

web.xml

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>^(?!\/rest).*$</url-pattern>              <!-- Doesn't work -->
</filter-mapping>

安全性.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:security="http://www.springframework.org/schema/security"
       xmlns:beans="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security.xsd">

    <security:http use-expressions="true" create-session="ifRequired" request-matcher="regex">
        <security:intercept-url pattern="^\/(css|fonts|help|images|layouts|scripts).*$" access="permitAll"/>
        <security:intercept-url pattern="^\/login.*$" access="permitAll"/>
        <security:intercept-url pattern="^\/logout.*$" access="permitAll"/>
        <security:intercept-url pattern="^\/accessDenied.cprms$" access="permitAll"/>

        <security:intercept-url pattern="^.*.jsp$" access="isAuthenticated()"/>
        <security:intercept-url pattern="^\/errors\/.*$" access="hasAnyAuthority('superRole','systemRole','supportRole','adminRole','businessRole','operationalRole','changePasswordRole')"/>
        <security:intercept-url pattern="^\/control\/.*$" access="isAuthenticated()"/>
        <security:intercept-url pattern="^\/control\/jobStatus.cprms$" access="isAuthenticated()"/>
        <security:intercept-url pattern="^\/sysad\/.*$" access="hasAnyAuthority('superRole','systemRole','supportRole')"/>
        <security:intercept-url pattern="^\/userad\/.*$" access="hasAnyAuthority('superRole','adminRole')"/>
        <security:intercept-url pattern="^\/myprofile\/.*$" access="hasAnyAuthority('superRole','systemRole','supportRole','adminRole','businessRole','operationalRole','changePasswordRole')"/>
        <security:intercept-url pattern="^\/config\/carpark\/carParkDetails.cprms$" access="isAuthenticated()"/>
        <security:intercept-url pattern="^\/config\/carpark\/.*$" access="hasAnyAuthority('superRole','systemRole','supportRole','adminRole','businessRole','operationalRole')"/>
        <security:intercept-url pattern="^\/config\/product\/.*$" access="hasAnyAuthority('superRole','systemRole','supportRole','adminRole','businessRole','operationalRole')"/>
        <security:intercept-url pattern="^\/config\/splevt\/.*$" access="hasAnyAuthority('superRole','systemRole','supportRole','adminRole','businessRole','operationalRole')"/>
        <security:intercept-url pattern="^\/config\/alert\/.*$" access="hasAnyAuthority('superRole','systemRole','supportRole','adminRole','businessRole','operationalRole')"/>
        <security:intercept-url pattern="^\/config\/location\/.*$" access="hasAnyAuthority('superRole','supportRole','nolocation')"/>
        <security:intercept-url pattern="^\/config\/competitor\/details\/.*$" access="hasAnyAuthority('superRole','systemRole','supportRole','adminRole','businessRole','operationalRole')"/>
        <security:intercept-url pattern="^\/config\/competitor\/product\/.*$" access="hasAnyAuthority('superRole','systemRole','supportRole','adminRole','businessRole','operationalRole')"/>
        <security:intercept-url pattern="^\/config\/consolidator\/interface\/.*$" access="hasAnyAuthority('superRole','adminRole')"/>
        <security:intercept-url pattern="^\/config\/consolidator\/details\/.*$" access="hasAnyAuthority('superRole','systemRole','supportRole','adminRole','businessRole','operationalRole')"/>
        <security:intercept-url pattern="^\/config\/consolidator\/product\/.*$" access="hasAnyAuthority('superRole','systemRole','supportRole','businessRole','operationalRole')"/>
        <security:intercept-url pattern="^\/monitor\/config\/.*$" access="hasAnyAuthority('superRole','systemRole','supportRole','adminRole','businessRole','operationalRole')"/>
        <security:intercept-url pattern="^\/monitor\/configure\/.*$" access="hasAnyAuthority('superRole','systemRole','supportRole','adminRole','businessRole','operationalRole')"/>
        <security:intercept-url pattern="^\/monitor\/operation\/.*$" access="hasAnyAuthority('superRole','systemRole','supportRole','adminRole','businessRole','operationalRole')"/>
        <security:intercept-url pattern="^\/recommendedSettings.cprms$" access="isAuthenticated()"/>
        <security:intercept-url pattern="^\/.*errors.cprms$" access="isAuthenticated()"/>
        <security:intercept-url pattern="^\/upload\/uploadExtract\/.*$" access="hasAnyAuthority('uploadExtractRole')"/>

        <security:intercept-url pattern="^\/.*$" access="isAuthenticated()"/>

        <security:form-login
                login-page="/loginRedirector.jsp"
                login-processing-url="/login"
                authentication-failure-handler-ref="authenticationFailureHandler"
                default-target-url="/welcome.jsp"
                always-use-default-target="true"
                username-parameter="j_username"
                password-parameter="j_password"
        />
        <security:logout logout-success-url="/loginRedirector.jsp" />

        <security:session-management invalid-session-url="/loginRedirector.jsp">
            <security:concurrency-control max-sessions="1" />
        </security:session-management>
        <security:csrf disabled="true"/>
    </security:http>

    <security:authentication-manager erase-credentials="false">
        <security:authentication-provider>
            <security:password-encoder ref="passwordEncoder" />
            <security:jdbc-user-service
                data-source-ref="globalDataSource"
                users-by-username-query="SELECT user_id AS `username`, PASSWORD AS `password`, IF(user_locked = 'N', 1, 0) AS `enabled` FROM `user` WHERE user_id = ?"
                authorities-by-username-query="SELECT u.user_id AS `username`, r.NAME AS `role` FROM `user` u INNER JOIN user_role ur ON ur.user_fk = u.user_pk INNER JOIN role AS r ON ur.role_fk = r.role_pk WHERE u.user_id = ?"
            />
        </security:authentication-provider>
        <security:authentication-provider ref="ssoAuthenticationProvider" />
    </security:authentication-manager>

    <beans:bean id="authenticationFailureHandler" class="com.ideas.carparkpro.core.service.impl.LoginFailureHandler" />
    <beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder"/>
    <beans:bean id="ssoAuthenticationProvider" class="com.ideas.carparkpro.core.service.impl.SSOAuthenticationProvider" />

</beans:beans>

【问题讨论】:

  • 看起来您正在为security.xml 中的每个控制器明确设置所有安全设置,在这种情况下,您需要为/rest 设置任何东西吗?我假设如果没有定义设置,它不会限制它。
  • @dbaltor 它似乎无法以某种方式工作。但是,我已经修复了它,同时在 web.xml 中一一列出了 Spring Security 需要跟踪的所有 URL。
  • 感谢您的反馈。我很高兴你最终找到了解决方案。

标签: java spring spring-security


【解决方案1】:

我从未使用过它,但我认为这对你有用:DelegatingFilterProxy

要使用它,您需要将下面的 sn-p 添加到您的web.xml

<filter>
    <filter-name>filterProxy</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>filterProxy</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

然后将filterChainProxy bean 配置为将/rest URL 列入白名单,同时将您需要的所有过滤器应用于一般情况。这是一个例子:

<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<constructor-arg>
    <list>
    <sec:filter-chain pattern="/rest/**" filters="none" />
    <sec:filter-chain pattern="/**" filters="
        UsernamePasswordAuthenticationFilter,
        basicAuthenticationFilter,
        formLoginFilter,
        securityContextPersistenceFilterWithASCTrue,
        exceptionTranslationFilter,
        filterSecurityInterceptor" />
    </list>
</constructor-arg>
</bean>

上面的顺序很重要。更严格的 URL 必须放在首位。

【讨论】:

    【解决方案2】:

    根据我对这个问题的评论,你可能不需要将控制器定义为没有任何安全设置。但如果你这样做了,你的security.xml 中已经有其他控制器在做类似的事情:

    <security:intercept-url pattern="^/rest/*$" access="permitAll"/>
    

    【讨论】:

    • 我有一种不同的方式来验证以/rest 开头的 URL,所以不确定这是否可行。
    猜你喜欢
    • 2016-07-17
    • 2016-03-16
    • 2011-03-24
    • 2014-05-11
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2016-09-10
    相关资源
    最近更新 更多