2014-03-05 78 views
1

在我的應用程序中,我使用LDAP身份驗證(稱爲ldap)。對於我的一個頁面,我需要使用基本的html彈出框(稱爲內部)進行自己的身份驗證。我得到BeanCreationExceptionSpring Security許多提供者

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChainProxy': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: A universal match pattern ('/**') is defined before other patterns in the filter chain, causing them to be ignored. Please check the ordering in your <security:http> namespace or FilterChainProxy bean configuration 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1512) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) ~[spring-context-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) ~[spring-context-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389) ~[spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294) ~[spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112) [spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] 
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973) [catalina.jar:7.0.52] 
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467) [catalina.jar:7.0.52] 
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:7.0.52] 
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559) [catalina.jar:7.0.52] 
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549) [catalina.jar:7.0.52] 
at java.util.concurrent.FutureTask.run(Unknown Source) [na:1.7.0_51] 
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.7.0_51] 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.7.0_51] 
at java.lang.Thread.run(Unknown Source) [na:1.7.0_51] 

這裏是我的配置:

<http authentication-manager-ref="internal">  
    <intercept-url pattern="/monitoring" access="ROLE_USER" /> 
    <http-basic /> 
</http> 

<http authentication-manager-ref="ldap" auto-config='true' use-expressions="true"> 
    <intercept-url pattern="/**" access="permitAll" /> 
    <form-login login-page='/' default-target-url='/login_ok' 
     always-use-default-target='true' authentication-failure-url="/login_failed" /> 
    <logout logout-success-url="/" /> 
</http> 

<authentication-manager id="internal"> 
    <authentication-provider> 
     <user-service> 
     <user name="monitoring" password="monitoring" authorities="ROLE_USER" /> 
     </user-service> 
    </authentication-provider> 
</authentication-manager> 

<authentication-manager erase-credentials="false" id="ldap"> 
    <ldap-authentication-provider 
     group-search-filter="${ldap.group-search-filter}" server-ref="ldapServer" 
     group-search-base="${ldap.group-search-base}" user-search-filter="${ldap.user-search-filter}" 
     user-search-base="${ldap.user-search-base}" group-role-attribute="${ldap.group-role-attribute}" 
     role-prefix="${ldap.role-prefix}"> 
    </ldap-authentication-provider> 
    <authentication-provider user-service-ref="userService" /> 
</authentication-manager> 

我明白爲什麼拋出異常,並知道圖案秩序和範圍是重要的,但不知道怎麼做是正確的。我想要的是,每個用戶都可以訪問「/ **」,但只有監視用戶可以訪問/監視(使用基本身份驗證)。在我想添加這個內部認證之前,一切正常。

回答

0

你需要做的改變是:

  • 確保有一個模式的第<http>。這是你現在問題的核心。兩個<http>匹配每個請求,所以第二個<http>從未考慮。要解決此問題,請添加模式屬性。
  • 確保爲監控用戶使用不同的角色。請記住,認證和授權是分離的。這意味着訪問/監控僅受用戶角色限制,而不受用戶身份驗證的限制。使用當前設置,用戶可以向LDAP身份驗證管理器進行身份驗證,並且如果他們被分配角色「ROLE_USER」,則他們可以訪問/監視並查看該URL。
  • 儘管沒有必要,但我們更新了第一個<http>的攔截網址以匹配每個網址。這是沒有必要的,因爲第一個<http>首先只用於/監視URL,但稍後有人更新模式屬性會更安全一些。

的變化的一個例子可以在下面看到:

<http authentication-manager-ref="internal" pattern="/monitoring">  
    <intercept-url pattern="/**" access="ROLE_MONITORING" /> 
    <http-basic /> 
</http> 

<http authentication-manager-ref="ldap" auto-config='true' use-expressions="true"> 
    <intercept-url pattern="/**" access="permitAll" /> 
    <form-login login-page='/' default-target-url='/login_ok' 
     always-use-default-target='true' authentication-failure-url="/login_failed" /> 
    <logout logout-success-url="/" /> 
</http> 

<authentication-manager id="internal"> 
    <authentication-provider> 
     <user-service> 
     <user name="monitoring" password="monitoring" authorities="ROLE_MONITORING" /> 
     </user-service> 
    </authentication-provider> 
</authentication-manager> 

<authentication-manager erase-credentials="false" id="ldap"> 
    <ldap-authentication-provider 
     group-search-filter="${ldap.group-search-filter}" server-ref="ldapServer" 
     group-search-base="${ldap.group-search-base}" user-search-filter="${ldap.user-search-filter}" 
     user-search-base="${ldap.user-search-base}" group-role-attribute="${ldap.group-role-attribute}" 
     role-prefix="${ldap.role-prefix}"> 
    </ldap-authentication-provider> 
    <authentication-provider user-service-ref="userService" /> 
</authentication-manager> 

有一件事我會考慮在移動監控用戶到LDAP。將該用戶置於內存實例中會鼓勵用戶不再維護(即應定期輪換密碼)。這還可以確保您的LDAP用戶和內部用戶之間不會發生任何衝突(例如,您如何知道ldap身份驗證中沒有名爲「monitoring」的用戶?)。最後它簡化了你的配置,你只需要配置一個<http>。如果HTTP基本標題存在,它仍然使用它進行身份驗證。

+0

好的。事情是,http標記沒有路徑屬性,所以XML中有錯誤。或者,我錯過了一些架構或東西?關於休息 - 我同意,它可以更好地組織:)。 – alvaro991

+0

對不起,路徑應該是模式。我已更新帖子 –

+0

是的,我想到了:)。將「路徑」更改爲「模式」解決了XML錯誤,但是當我想訪問「/ monitoring」時,我得到403 - 訪問被拒絕。沒有顯示身份驗證表單,只是錯誤 – alvaro991

相關問題