配置 Spring 安全性 4,以便可以在 XML 中使用 "<sec:authorize url='...' />" 标记



我有一个工作的java 8 web应用程序,它使用Spring框架4.2和Spring Security 4.0.2一起通过Jasig CAS(中央认证服务)处理身份验证,对我们的Active Directory服务器使用LDAP。

目前,我像这样使用"Authorize"JSP标记库(http://docs.spring.io/spring-security/site/docs/4.0.2.RELEASE/reference/htmlsingle/#taglibs-authorize)…

<sec:authorize var="allowRename" access="hasRole('ROLE_TEST_RENAME')" />
<input id="allowRename" type="hidden" value="${allowRename}" />

此方法的缺点是在视图中直接引用Active Directory安全组。我宁愿不这么做。相反,我希望改变它,使它看起来像这样…

<sec:authorize var="allowRename" url="/rename.json" />
<input id="allowRename" type="hidden" value="${allowRename}" />

这样,我可以在一个地方配置访问-在spring安全配置。

根据文档,要在授权标签上使用url属性,在我的应用程序上下文中必须有一个WebInvocationPrivilegeEvaluator的实例。当我使用安全名称空间时,它不是xml配置文件中的基本名称空间-因此我理解我必须手动声明DefaultWebInvocationPrivilegeEvaluator类的实例。然而,该类的构造函数接受AbstractSecurityInterceptor类型的单个参数,据我所见,我没有对任何此类参数的引用。

这是我的(编辑,自然)配置-有人知道如何修改它,以便我可以声明一个DefaultWebInvocationPrivilegeEvaluator bean与一个单一的构造函数参数引用FilterSecurityInterceptor?

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:security="http://www.springframework.org/schema/security"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd">
    <security:http entry-point-ref="casEntryPoint">
        <security:intercept-url pattern="/rename.json" method="POST" 
            access="hasRole('ROLE_TEST_RENAME')" />
        <security:intercept-url pattern="/delete.json" method="POST" 
            access="hasRole('ROLE_TEST_DELETE')" />
        <security:intercept-url pattern="/restore.json" method="POST" 
            access="hasRole('ROLE_TEST_DELETE')" />
        <security:intercept-url pattern="/**" 
            access="hasRole('ROLE_TEST_USERS')" />
        <security:custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER" />
        <security:custom-filter ref="singleLogoutFilter" before="CAS_FILTER" />
        <security:custom-filter ref="casFilter" position="CAS_FILTER" />
        <security:logout logout-success-url="${cas.server.rootUrl}/logout" 
            invalidate-session="true" />
    </security:http>
    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider ref="casAuthenticationProvider" />
    </security:authentication-manager>
    <bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
        <constructor-arg value="ldap://ldap.test.com:389/dc=test,dc=com"/>
        <property name="url" value="ldap://ldap.test.com:389/" />
        <property name="base" value="dc=test,dc=com" />
        <property name="pooled" value="true" />
        <property name="userDn" value="${ad.userDn}" />
        <property name="password" value="${ad.password}" />
    </bean>
    <bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
        <constructor-arg name="searchBase" value="ou=User Accounts,ou=TEST" />
        <constructor-arg name="searchFilter" value="(sAMAccountName={0})" />
        <constructor-arg ref="contextSource" />
    </bean>
    <bean id="authoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
        <constructor-arg ref="contextSource" />
        <constructor-arg value="ou=Group Accounts,ou=TEST" />
        <property name="groupRoleAttribute" value="cn" />
        <property name="searchSubtree" value="true" />
        <property name="rolePrefix" value="ROLE_" />
        <property name="defaultRole" value="ROLE_USER" />
        <property name="convertToUpperCase" value="true" />
    </bean>
    <bean id="userDetailsMapper" class="com.test.security.auth.ActiveDirectoryUserDetailsMapper" />
    <bean id="ldapUserDetailsService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
        <constructor-arg ref="userSearch" />
        <constructor-arg ref="authoritiesPopulator" />
        <property name="userDetailsMapper" ref="userDetailsMapper" />
    </bean>
    <!-- handles a Single Logout Request from the CAS Server -->
    <bean id="singleLogoutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter">
        <property name="casServerUrlPrefix" value="${cas.server.secureUrl}" />
    </bean>
    <!-- redirects to the CAS Server to signal Single Logout should be performed -->
    <bean id="requestSingleLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
        <constructor-arg value="${cas.client.contextRootUrl}/logout" />
        <constructor-arg>
            <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
        </constructor-arg>
        <property name="filterProcessesUrl" value="/logout/cas" />
    </bean>
    <bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
        <property name="service" value="${cas.client.contextRootUrl}/login/cas" />
        <property name="authenticateAllArtifacts" value="true" />
        <property name="sendRenew" value="false" />
    </bean>
    <bean id="casEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
        <property name="loginUrl" value="${cas.server.rootUrl}/login" />
        <property name="serviceProperties" ref="serviceProperties" />
    </bean>
    <bean id="casFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
        <property name="authenticationManager" ref="authenticationManager" />
        <property name="serviceProperties" ref="serviceProperties" />
    </bean>
    <bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
        <property name="authenticationUserDetailsService">
            <bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
                <constructor-arg ref="ldapUserDetailsService" />
            </bean>
        </property>
        <property name="serviceProperties" ref="serviceProperties" />
        <property name="ticketValidator">
            <bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
                <constructor-arg index="0" value="${cas.server.rootUrl}" />
            </bean>
        </property>
        <property name="key" value="test-application" />
    </bean>
</beans>

只是为了澄清,每当我使用我在最初的帖子中描述的授权标签时,它总是解析为true。问题是,在某些情况下,根据我登录的身份,它应该被解析为false

我刚刚找到了原因,现在它正常工作了。

基本上,问题就在这里…

<sec:authorize var="allowRename" url="/rename.json" />

如果你看一下上面的配置,你会看到"/rename. conf"url有method="POST"限制。为了使标记正常工作,我必须修改它,以便它也指定方法…

<sec:authorize var="allowRename" url="/rename.json" method="POST" />

谢谢大家的帮助。

相关内容

最新更新