java 无法正确获取 spring-security.xml

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5973635/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 13:47:08  来源:igfitidea点击:

Can't get spring-security.xml right

javaspring-securityjavabeansservlet-filters

提问by zclark

I have my spring security set up to do basic authentication to a database with no issues, however I would like to add custom login/logout and admin pages as well as md5 encryption on passwords w/ salt.

我已将 spring 安全设置为对数据库进行基本身份验证,没有任何问题,但是我想添加自定义登录/注销和管理页面,以及对带盐的密码进行 md5 加密。

I keep hitting walls trying to get either of these features to work, and all the examples online seem to be using and declaring like that instead of using bean declarations like I am. This makes it more difficult because options in examples don't seem to directly translate into bean properties.

我一直在努力使这些功能中的任何一个工作,而且所有在线示例似乎都在使用和声明这样的方式,而不是像我一样使用 bean 声明。这使得它变得更加困难,因为示例中的选项似乎没有直接转换为 bean 属性。

Here is my web.xml - I am using Spring Security 3.0:

这是我的 web.xml - 我使用的是 Spring Security 3.0:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/applicationContext.xml
        /WEB-INF/builder-servlet.xml
        /WEB-INF/builder-service.xml
        /WEB-INF/builder-data.xml
        /WEB-INF/builder-security.xml
    </param-value>
</context-param>

<servlet>
    <servlet-name>builder</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>builder</servlet-name>
    <url-pattern>*.htm</url-pattern>
    <url-pattern>*.docx</url-pattern>
</servlet-mapping>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>targetClass</param-name>
        <param-value>org.springframework.security.web.FilterChainProxy</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<session-config>
    <session-timeout>
        30
    </session-timeout>
</session-config>
<welcome-file-list>
    <welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
</web-app>

And here is my builder-security (mind the disorganization):

这是我的建设者安全(注意混乱):

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:s="http://www.springframework.org/schema/security"
   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.0.xsd">

<!--<s:authentication-manager>
    <s:authentication-provider ref="authenticationProvider"/>
</s:authentication-manager>-->

<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
    <s:filter-chain-map path-type="ant">
        <s:filter-chain pattern="/**"
            filters="securityContextPersistenceFilter,
                    exceptionTranslationFilter,
                    authenticationProcessingFilter,
                    filterSecurityInterceptor,
                    anonymousAuthenticationFilter"/>
    </s:filter-chain-map>
</bean>

<bean id="securityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>

<bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter">
    <property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
</bean>

<bean id="authenticationProcessingFilter" class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
    <property name="authenticationManager" ref="authenticationManager"/>
    <property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
</bean>

<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
    <property name="providers">
        <list>
            <ref bean="authenticationProvider"/>
            <ref bean="anonymousAuthenticationProvider"/>
        </list>
    </property>
</bean>

<bean id="authenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
    <!--<property name="passwordEncoder" ref="md5PasswordEncoder"/>-->
    <!--<property name="saltSource" ref="systemWideSaltSource"/>-->
    <property name="userDetailsService" ref="authenticationDao"/>
    <property name="userCache" ref="userCache"/>
</bean>

<bean id="md5PasswordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder">

</bean>

<bean id="systemWideSaltSource" class="org.springframework.security.authentication.dao.SystemWideSaltSource">
    <property name="systemWideSalt" value="XXXX"/>
</bean>

<bean id="userCache" class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache">
    <property name="cache" ref="ehcache"/>
</bean>

<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
    <property name="cacheManager" ref="cacheManager"/>
    <property name="cacheName" value="userCache"/>
</bean>

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="configLocation" value="ehcache.xml"/>
</bean>

<bean id="authenticationDao" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
    <property name="dataSource" ref="dataSource"/>
</bean>

<!--<bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
    <property name="realmName" value="SpecBuilder"/>
</bean>-->
<bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <property name="loginFormUrl" value="/login.html"/>
</bean>

<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased">
    <property name="decisionVoters">
        <list>
            <ref bean="voter"/>
        </list>
    </property>
</bean>

<bean id="voter" class="org.springframework.security.access.vote.RoleVoter">
    <property name="rolePrefix" value="ROLE_"/>
</bean>

<bean id="anonymousAuthenticationFilter" class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
    <property name="key" value="foobar"/>
    <property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS"/>
</bean>

<bean id="anonymousAuthenticationProvider" class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
    <property name="key" value="foobar"/>
</bean>

<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
    <property name="authenticationManager" ref="authenticationManager"/>
    <property name="accessDecisionManager" ref="accessDecisionManager"/>
    <property name="objectDefinitionSource">
        <s:filter-invocation-definition-source>
            <s:intercept-url pattern="/login*" access="ROLE_ANONYMOUS"/>
            <s:intercept-url pattern="/**" access="ROLE_USER"/> <!-- isAuthenticated() probably better -->
        </s:filter-invocation-definition-source>
    </property>
</bean>

</beans>

Right now I am trying to get login.html to all anonymous access, yet all I get is an infinite security loop.

现在我试图让 login.html 进行所有匿名访问,但我得到的只是一个无限的安全循环。

Is there a reason I shouldn't be using bean declarations for this? Because not very many people seem to be doing so. I'd rather not change the whole thing if there is no advantage to doing it. There has to be something wrong with it or a better place to go to get bean declaration references and examples, because most all searches turn up the other style of implementing spring security.

有什么理由我不应该为此使用 bean 声明吗?因为似乎没有多少人这样做。如果这样做没有任何好处,我宁愿不改变整个事情。它一定有问题,或者有更好的地方去获取 bean 声明引用和示例,因为大多数搜索都出现了另一种实现 spring 安全性的风格。

采纳答案by zclark

After a fair bit of research and testing, I've solved it. The built in security namespace does a good chunk of the work for you. Creating each filter and manager bean by bean is a good way to customize things, but it makes it quite bit more difficult and it's not really necessary.

经过相当多的研究和测试,我已经解决了它。内置的安全命名空间为您做了大量的工作。逐个创建每个过滤器和管理器 bean 是一种自定义事物的好方法,但这会使它变得更加困难,而且并不是真正必要的。

My final code involves a custom user class that includes a salt value and a custom dao class to enforce the use of the salt. Everything else is done through use of the security namespace.

我的最终代码涉及一个自定义用户类,其中包含一个 salt 值和一个自定义 dao 类来强制使用 salt。其他一切都是通过使用安全命名空间来完成的。

builder-security.xml

builder-security.xml

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:s="http://www.springframework.org/schema/security"
   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.0.xsd">

<s:http auto-config="true" use-expressions="true">
    <s:intercept-url pattern="/login*" access="permitAll"/>
    <s:intercept-url pattern="/*" access="hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')"/>
    <s:form-login login-page="/login.html"/>
    <s:logout logout-url="/logout"/>
</s:http>

<s:authentication-manager alias="authenticationManager">
    <s:authentication-provider user-service-ref="userDetailsService">
        <s:password-encoder ref="passwordEncoder">
            <s:salt-source ref="saltSource"/>
        </s:password-encoder>            
    </s:authentication-provider>
</s:authentication-manager>

<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder"/>

<bean class="org.springframework.security.authentication.dao.ReflectionSaltSource" id="saltSource">
    <property name="userPropertyToUse" value="salt"/>
</bean>

<bean id="userDetailsService" class="builder.webapp.security.CustomJdbcDaoImpl">
    <property name="dataSource" ref="dataSource"/>
    <property name="enableAuthorities" value="true"/>
    <property name="enableGroups" value="false"/>
    <property name="usersByUsernameQuery"
              value="select username,password,enabled,salt from users where username = ?"/>
</bean>

</beans>

回答by Random