如何允许用户使用Spring Security覆盖? - java

在我的Spring MVC Web应用程序中,某些区域只有具有足够特权的用户才能访问。我不仅要有一条“拒绝访问”消息,还需要允许用户以其他用户身份登录才能使用这些页面(有点像覆盖)。

如何使用Spring Security做到这一点?

这是我想要的流程,其中包含更多细节:

  • 用户A从外部应用程序进入页面X并通过标头
  • 进行身份验证

  • 用户A没有使用页面X的权限,因此被带到登录屏幕,并显示一条消息,指示他们必须以具有足够特权的用户身份登录才能使用此页面
  • 用户B登录并具有足够的特权,并被带到第X页。
  • 注意:X页面有一个很大的长查询字符串,需要保留。

    如何使用Spring Security做到这一点?

    这是我的 Spring 安全配置文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="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-3.0.xsd
                http://www.springframework.org/schema/security 
                http://www.springframework.org/schema/security/spring-security-3.1.xsd">
    
        <debug />
    
        <global-method-security pre-post-annotations="enabled">
            <!-- AspectJ pointcut expression that locates our "post" method and applies 
                security that way <protect-pointcut expression="execution(* bigbank.*Service.post*(..))" 
                access="ROLE_TELLER"/> -->
        </global-method-security>
    
        <!-- Allow anyone to get the static resources and the login page by not applying the security filter chain -->
        <http pattern="/resources/**" security="none" />
        <http pattern="/css/**" security="none" />
        <http pattern="/img/**" security="none" />
        <http pattern="/js/**" security="none" />
    
        <!-- Lock everything down -->
        <http 
            auto-config="true"
            use-expressions="true" 
            disable-url-rewriting="true">
    
            <!-- Define the URL access rules -->
            <intercept-url pattern="/login" access="permitAll" />
            <intercept-url pattern="/about/**" access="permitAll and !hasRole('blocked')" />
            <intercept-url pattern="/users/**" access="hasRole('user')" />
            <intercept-url pattern="/reviews/new**" access="hasRole('reviewer')" />
            <intercept-url pattern="/**" access="hasRole('user')" />
    
            <form-login 
                login-page="/login" />
    
            <logout logout-url="/logout" /> 
    
            <access-denied-handler error-page="/login?reason=accessDenied"/>
    
            <!-- Limit the number of sessions a user can have to only 1 -->
            <session-management>
                <concurrency-control max-sessions="1" />
            </session-management>
        </http>
    
        <authentication-manager>
            <authentication-provider ref="adAuthenticationProvider" />
            <authentication-provider>
                <user-service>
                    <user name="superadmin" password="superadminpassword" authorities="user" />
                </user-service>
            </authentication-provider>
        </authentication-manager>
    
        <beans:bean id="adAuthenticationProvider" class="[REDACTED Package].NestedGroupActiveDirectoryLdapAuthenticationProvider">
            <beans:constructor-arg value="[REDACTED FQDN]" />
            <beans:constructor-arg value="[REDACTED LDAP URL]" />
            <beans:property name="convertSubErrorCodesToExceptions" value="true" />
            <beans:property name="[REDACTED Group Sub-Tree DN]" />
            <beans:property name="userDetailsContextMapper" ref="peerReviewLdapUserDetailsMapper" />
        </beans:bean>
    
        <beans:bean id="peerReviewLdapUserDetailsMapper" class="[REDACTED Package].PeerReviewLdapUserDetailsMapper">
            <beans:constructor-arg ref="UserDAO" />
        </beans:bean>
    
    </beans:beans>
    

    我正在使用Spring Security 3.1 Active Directory连接功能的稍作修改的版本。所做的修改仅加载用户的所有组,包括通过组嵌套到达的组,而不是仅加载用户直接所属的组。我还使用了一个自定义用户对象,该对象中嵌入了我的应用程序的User对象,一个自定义LDAP映射器执行普通的LDAP映射,然后添加了我的用户。

    有一个尚未实施的特殊身份验证方案,其中基于从外部应用程序(或通过Kerberos)以单点登录方式传递的用户名对用户进行身份验证。

    参考方案

    您如何检查角色?

    如果您在这样的安全上下文中定义它们:

    <intercept-url pattern="/adminStuff.html**" access="hasRole('ROLE_ADMIN')" />
    

    您可以在 defaultFailureUrl 中设置SimpleUrlAuthenticationFailureHandler,当特权较低的用户尝试访问受保护的URL时,FaliureHandler应该将您重定向到defaultFailureUrl,它可能是您的登录页面。

    您可以在filter位置的spring docs on custom filters中注入FaliureHandler

    <bean id="myFaliureHandler" 
        class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
        <property name="defaultFailureUrl" value="http://yourdomain.com/your-login.html"/>
    </bean>
    
    <bean id="myFilter"
       class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
       <property name="authenticationFailureHandler" ref="myFaliureHandler"/>
    </bean>    
    
    <http>
      <custom-filter position="FORM_LOGIN_FILTER" ref="myFilter" />
    </http>
    

    在评论中回答1)。

    与给定名称空间配置的情况相比,这比我想象的要多得多的工作。

    您需要做的是删除FORM_LOGIN_FILTER定义,而不是添加一个“自定义” <form-login>(这是处理UsernamePasswordAuthenticationFilter元素的过滤器)。

    您还需要删除<form-login>

    因此,您的配置应类似于:

    <bean id="myFaliureHandler" 
        class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
        <property name="defaultFailureUrl" value="http://yourdomain.com/your-login.html"/>
    </bean>
    
    <bean id="myFilter"
       class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
       <property name="authenticationFailureHandler" ref="myFaliureHandler"/>
       <!-- there are more required properties, but you can read about them in the docs -->
    </bean>
    
    <bean id="loginUrlAuthenticationEntryPoint"
       class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
       <property name="loginFormUrl" value="/login"/>
    </bean>
    
    <http entry-point-ref="authenticationEntryPoint" auto-config="false">
    
      <!-- your other http config goes here, just omit the form-login element and the access denied handler -->
    
      <custom-filter position="FORM_LOGIN_FILTER" ref="myFilter" />
    </http>
    

    通常,如果还没有的话,也可以看看ojit_a。当前,我们在我当前的公司中使用此配置,如果页面上没有必需的特权,则强制用户重新登录。

    SOAPFaultException部署在Tomcat上时,但在GlassFish中工作正常 - java

    朋友们,我一直在尝试很多,阅读了很多论坛,但无法理解为什么出现此问题。我使用契约优先方法创建了一个Jax-WS WebService。创建WSDL和XSD,然后使用wsimport工具生成其余工件,为SEI提供实现。将WebService应用程序部署到Eclipse Helios中的GlassFish(Glassfish适配器和Eclipse中安装的插件)。…

    Java Applet的URLConnection与PHP无效 - java

    我已经研究了Oracle文档和示例,但仍然无法正常工作。我有一个Java Applet,它只是尝试使用URLConnection和OutputStreamWriter通过POST将文本字段发送到PHP脚本。 Java方面似乎工作正常,没有引发异常,但是PHP在我的页面上未显示任何输出。我是PHP新手,因此请耐心等待。这是相关的Java部分: try { UR…

    页面加载而不是提交时发生struts验证 - java

    请原谅我;我对Struts有点陌生。我遇到一个问题,即页面加载而不是我实际提交表单时发生了验证。我整天都在论坛上搜寻和搜寻,没有任何运气。我显然做错了一些事情,应该很容易确定,但是我还没有发现问题所在。这是我的struts.xml的片段:<action name="*Test" method="{1}" clas…

    DataSourceTransactionManager和JndiObjectFactoryBean和JdbcTemplate的用途是什么? - java

    以下的用途是什么:org.springframework.jdbc.core.JdbcTemplate org.springframework.jdbc.datasource.DataSourceTransactionManager org.springframework.jndi.JndiObjectFactoryBean <tx:annotatio…

    Java-如何导入外部软件包? - java

    我对Java还是比较陌生。我已经尝试寻找解决方案,但是我想我对Java的了解还不够,甚至不知道我应该寻找什么。我想尝试语音识别,所以我下载了CMU的Sphinx-4源代码并进行了编译。一旦一切正常,我就可以运行包含的演示了。接下来,我在包含Sphinx-4目录的目录中为我的代码创建了目录(/ Jarvis /)。在Sphinx-4源目录中,有一长串目录指向我…