春季安全 - 记住,我有多个身份验证提供身份验证 [英] Spring security - remember-me authentication with multiple authentication providers

查看:231
本文介绍了春季安全 - 记住,我有多个身份验证提供身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Spring Security的3.2.0在我的Web应用程序。

I'm using Spring security 3.2.0 in my web application.

我有两个安全角色:与存储在数据库中的凭据用户和管理员枝条保存在配置文件中的凭据。

I have two security roles: users with the credentials stored in database and administrators withe credentials stored in configuration file.

直到我打开记得,我验证它工作正常。这里是我的 security.xml文件配置:

It works fine until I turn on remember-me authentication. Here is my security.xml config:

<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd
   http://www.springframework.org/schema/security
   http://www.springframework.org/schema/security/spring-security-3.2.xsd">

    <security:global-method-security secured-annotations="enabled"/>

    <security:http auto-config="true">
        <security:remember-me key="myAppKey" user-service-ref="adminSrv"/>
        <security:remember-me key="myAppKey" user-service-ref="jdbcUserSrv"/>
        <security:form-login login-page="/login" default-target-url="/"
            authentication-failure-url="/loginfailed" />
        <security:logout logout-success-url="/logout"/>
    </security:http>

    <security:authentication-manager>
        <security:authentication-provider>
            <security:jdbc-user-service data-source-ref="dataSource" id="jdbcUserSrv"
                                        users-by-username-query="/* SQL query */"
                                        authorities-by-username-query="/* Another SQL query */"
                    />
        </security:authentication-provider>
        <security:authentication-provider>
            <security:user-service id="adminSrv">
                <security:user name="admin" authorities="ROLE_ADMIN" password="passwd"/>

            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
</beans>

当我以管理员身份登录它去罚款。

When I log in as administrator it goes fine.

当我尝试以用户身份登录它抛出异常的j_spring_security_check:

When I try to log in as user it throws exception on j_spring_security_check:

HTTP ERROR 500

Problem accessing /mercury/j_spring_security_check. Reason:

    user1
Caused by:

org.springframework.security.core.userdetails.UsernameNotFoundException: user1
    at org.springframework.security.provisioning.InMemoryUserDetailsManager.loadUserByUsername(InMemoryUserDetailsManager.java:113)
    at org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices.onLoginSuccess(TokenBasedRememberMeServices.java:178)
    at org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices.loginSuccess(AbstractRememberMeServices.java:262)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.successfulAuthentication(AbstractAuthenticationProcessingFilter.java:324)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.successfulAuthentication(AbstractAuthenticationProcessingFilter.java:298)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:235)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
    at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

但是,如果它成功通过验证,如果我打开我的应用程序的索引页它显示登录为USER1。

However if it is authenticated successfully and if I open my application index page it is shown logged in as "user1".

如果记得,我配置为jdbcUserSrv那张配置为adminSrv出现admin用户则错误之前。

If remember-me config for jdbcUserSrv goes before the config for adminSrv then the error appears for "admin" user.

当前配置工作正常,而不记得,我的选择,但我需要他们启用。

Current configuration works fine without the remember-me options but I need them to be enabled.

请指点我如何避免这些错误。

Please advice me how to avoid these errors.

推荐答案

有两个remember-me的元素被简单地覆盖彼此。拥有多个的UserDetailsS​​ervice实例可以让你陷入困境了。例如,我想你可能有你的用户相关的数据。如果双方在记忆和JDBC的UserDetailsS​​ervice实例中存在一个名为admin的用户的话,你怎么知道哪个管理用户的数据属于?由于这个原因,很可能最好使用单个的UserDetailsS​​ervice

Having two remember-me elements is simply overriding one another. Having multiple UserDetailsService instances can get you into trouble too. For example, I assume you likely have data associated with your users. If a user named admin exists in both the in memory and the jdbc UserDetailsService instances, then how do you know which admin user the data belongs to? For this reason, it is likely best to use a single UserDetailsService.

另外,您可以创建一个UserDetailsS​​ervice中委托给多个的UserDetailsS​​ervice实例。例如:

Alternatively you can create a UserDetailsService that delegates to multiple UserDetailsService instances. For example:

public class DelegatingUserDetailsService implements UserDetailsService {
    private final List<UserDetailsService> userDetailsServices;

    public DelegatingUserDetailsService(
            List<UserDetailsService> userDetailsServices) {
        this.userDetailsServices = userDetailsServices;
    }

    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {
        RuntimeException last = null;
        for(UserDetailsService uds : userDetailsServices) {
            try {
                return uds.loadUserByUsername(username);
            } catch(RuntimeException error) {
                last = error;
            }
        }
        throw last;
    }
}

然后您可以记住,我用它来代替:

Then you can have remember-me use it instead:

<bean id="delegateUds" class="DelegatingUserDetailsService">
     <constructor-arg>
         <list>
             <ref bean="jdbcUserSrv"/>
             <ref bean="adminSrv"/>
         </list>
     </constructor-arg>
</bean>
<security:http auto-config="true">
    <security:remember-me key="myAppKey" user-service-ref="delegateUds"/>
    <security:form-login login-page="/login" default-target-url="/"
        authentication-failure-url="/loginfailed" />
    <security:logout logout-success-url="/logout"/>
</security:http>

这篇关于春季安全 - 记住,我有多个身份验证提供身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆