簡體   English   中英

Spring Security的許多提供商

[英]Spring Security many providers

在我的應用程序中,我使用LDAP身份驗證(稱為ldap )。 對於我的頁面之一,我需要使用基本的html彈出窗口(稱為internal )進行身份驗證。 我得到BeanCreationException

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>

我了解為什么會引發異常,並且知道模式順序和作用域很重要,但不知道如何正確執行。 我想要的是,每個用戶都可以訪問“ / **”, 但是只有監視用戶可以訪問/ monitoring(已通過基本身份驗證)。 在我想添加此內部身份驗證之前,一切工作都很好。

您需要進行的更改是:

  • 確保第一個<http>具有模式。 這是您當前問題的核心。 兩個<http>匹配每個請求,因此永遠不會考慮第二個<http> 要解決此問題,請添加pattern屬性。
  • 確保為監視用戶使用其他角色。 請記住,身份驗證和授權是分離的。 這意味着訪問/監視僅受用戶角色的限制,而不受用戶身份驗證的方式的限制。 在當前設置下,用戶可以向ldap AuthenticationManager進行身份驗證,如果為他們分配了角色“ ROLE_USER”,則他們可以訪問/ monitoring並查看該URL。
  • 雖然不是必需的,但我們會更新第一個<http>的攔截URL以在每個URL上都匹配。 因為第一個<http>首先僅用於/ monitoring URL,所以這不是必需的,但是如果以后有人更新了pattern屬性,這會更安全一些。

更改示例如下:

<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 Basic標頭,它仍將使用它進行身份驗證。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM