0

우리는 한동안 봄 보안 환경에서 단일 인증 관리자 (LDAP)로 작업 해 왔지만 지금은 두 개의 인증 관리자는 Login-LDAP 용이고 다른 하나는 IP 기반 보안 용입니다. IP 기반 보안은 전역 필터로 사용되며 로그인을 위해서는 LDAP로만 사용됩니다. 따라서 두 개의 인증 관리자. 우리는 비슷한 문제로 해결책을 시도했지만 여전히 같은 문제에 직면했습니다.Spring Security 4.0.2- 다중 인증 관리자 - 이름이 'org.springframework.security.filterChainProxy'인 빈을 생성하는 오류

오류 코드는 다음과 같습니다

org.springframework.beans.factory.BeanCreationException : 오류 이름 'org.springframework.security.filterChainProxy'로 콩을 만들 : 초기화 방법의 호출에 실패; 중첩 예외는 java.lang.IllegalArgumentException : 범용 일치 패턴 ('/ **') **은 필터 체인에있는 다른 패턴 앞에 정의되어 무시됩니다. 네임 스페이스 또는의 FilterChainProxy 빈 구성

web.xml의 순서를 확인하시기 바랍니다

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> 

<filter> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

<!-- needed for ContextLoaderListener --> 
<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value> 
     /WEB-INF/spring/application-context.xml 
     /WEB-INF/spring/security-context.xml 
    </param-value> 
</context-param> 

<!-- Bootstraps the root web application context before servlet initialization --> 
<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 
<servlet> 
    <servlet-name>dispatcher-servlet</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/spring/dispatcher-servlet.xml</param-value> 
    </init-param> 
</servlet> 
<servlet-mapping> 
    <servlet-name>dispatcher-servlet</servlet-name> 
    <url-pattern>/</url-pattern> 
</servlet-mapping> 

응용 프로그램의 context.xml

<?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:jdbc="http://www.springframework.org/schema/jdbc" 
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd 
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> 

     <tx:annotation-driven/> 

    <jdbc:embedded-database id="datasource" type="H2"> 
     <jdbc:script location="classpath:init.sql"/>  
    </jdbc:embedded-database> 

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     <property name="dataSource" ref="datasource"/> 
     <property name="persistenceUnitName" value="autoservice"/> 
    </bean> 

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
     <property name="entityManagerFactory" ref="entityManagerFactory"/> 
    </bean> 

    <jpa:repositories base-package="com.oreilly.security.domain.repositories"/> 

Security.xml

<?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" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> 

    <context:component-scan base-package="com.oreilly.security"/> 
    <bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler" /> 

     <security:http use-expressions="false" authentication-manager-ref="LDAPAuth"> 
     <security:form-login login-page="/login" 
      login-processing-url="/login" username-parameter="custom_username" 
      password-parameter="custom_password" default-target-url="/appointments/" 
      always-use-default-target="true" authentication-failure-url="/login?error=true" /> 

     <security:logout logout-url="/logout" 
      logout-success-url="/login?logout=true" /> 

     <security:intercept-url pattern="/appointments/*" 
      access="ROLE_USER,ROLE_ADMIN" /> 
     <security:intercept-url pattern="/schedule/*" 
      access="ROLE_ADMIN" /> 

    </security:http> 

    <security:http use-expressions="false" authentication-manager-ref="IpAuth"> 
     <security:form-login login-page="/login" 
      login-processing-url="/login" username-parameter="custom_username" 
      password-parameter="custom_password" default-target-url="/appointments/" 
      always-use-default-target="true" authentication-failure-url="/login?error=true" /> 

     <security:logout logout-url="/logout" 
      logout-success-url="/login?logout=true" /> 

     <security:intercept-url pattern="/**" 
      access="ROLE_USER,ROLE_ADMIN" />  
    </security:http> 



    <security:authentication-manager id ="IpAuth"> 
     <security:authentication-provider ref="customAuthenticationProvider"/> 
    </security:authentication-manager> 

    <security:authentication-manager id = "LDAPAuth"> 
     <security:ldap-authentication-provider user-search-filter="(uid={0})" 
      group-search-base="ou=groups" group-search-filter="(uniqueMember={0})" 
      server-ref="ldapServer" user-context-mapper-ref="contextMapper" role-prefix="ROLE_" 
      group-role-attribute="cn"/> 
    </security:authentication-manager> 

    <security:ldap-server id="ldapServer" url="ldap://localhost:10389/dc=oreilly,dc=com" 
     manager-dn="uid=admin,ou=system" manager-password="secret"/> 

</beans> 
친절

우리가이 문제를 해결하는 얻는 방법을 알려주는,

답변

0

:-) 일 동안 갇혀있다 당신에게 말하고있는 것은 하나 이상의 보편적 인 패턴 매칭을 가지고있다 사용자의 보안 설정에서 HTTP 섹션 :

<security:http use-expressions="false" authentication-manager-ref="LDAPAuth"> 
     <security:form-login login-page="/login" 
       login-processing-url="/login" username-parameter="custom_username" 
       password-parameter="custom_password" default-target-url="/appointments/" 
       always-use-default-target="true" authentication-failure-url="/login?error=true" /> 

      <security:logout logout-url="/logout" 
       logout-success-url="/login?logout=true" /> 

      <security:intercept-url pattern="/appointments/*" 
       access="ROLE_USER,ROLE_ADMIN" /> 
      <security:intercept-url pattern="/schedule/*" 
       access="ROLE_ADMIN" /> 

</security:http> 

<security:http use-expressions="false" authentication-manager-ref="IpAuth"> 
      <security:form-login login-page="/login" 
       login-processing-url="/login" username-parameter="custom_username" 
       password-parameter="custom_password" default-target-url="/appointments/" 
       always-use-default-target="true" authentication-failure-url="/login?error=true" /> 

      <security:logout logout-url="/logout" 
       logout-success-url="/login?logout=true" /> 

      <security:intercept-url pattern="/**" 
       access="ROLE_USER,ROLE_ADMIN" />  
</security:http> 

개 이상의 <security:http /> 요소를 가지고 싶다면, 당신은 마지막을 제외하고 모두에 패턴을 적용해야합니다. 예를 들어 사용자의 설정에 따라

<security:http pattern="/zone1/*" ... /> 
<security:http pattern="/zone2/*" ... /> 
... 
<security:http ... /> <!-- the last one does not need to apply a pattern --> 

, 첫 번째 security:http 요소에 두 intercept-url 패턴 (/appointmens/**, /schedule/**)가 있습니다. 당신은 (this 대답 기준) 최초의 security:http 요소에 정규식 정규 적용을 시도 할 수 있습니다 :

<security:http request-matcher="regex" pattern="^/(appointments|schedule)(/(\S)+)+$" 
       use-expressions="false" authentication-manager-ref="LDAPAuth" > 
... 
</security:http> 
<security:http use-expressions="false" authentication-manager-ref="IpAuth"> 
... 
</security> 
  • 은 내가 만든 수있는 오타 나 오류를 방지하기 위해 정규식을 확인하시기 바랍니다.

더 자세히 살펴보면 서로 다르다는 것을 알았습니다. authentication-manager을 사용해야합니다. 어쩌면 스프링 보안이 동시에 여러 인증 공급자를 관리 할 수 ​​있기 때문에 동일한 관리자에서 두 개의 authentication-providers을 섞어보십시오. 하나의 공급자와 다른 사람 (또는 다른 사람)에게 로그인 요청을 확인한 다음 그에 따라 행동 할 수 있습니다.

이 더 많거나 적은 같은 것 :

<?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" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> 

    <context:component-scan base-package="com.oreilly.security"/> 
    <bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler" /> 

    <security:http use-expressions="false" authentication-manager-ref="authenticationManager"> 
     <security:form-login login-page="/login" 
      login-processing-url="/login" username-parameter="custom_username" 
      password-parameter="custom_password" default-target-url="/appointments/" 
      always-use-default-target="true" authentication-failure-url="/login?error=true" /> 

     <security:logout logout-url="/logout" 
      logout-success-url="/login?logout=true" /> 

     <security:intercept-url pattern="/appointments/*" 
      access="ROLE_USER,ROLE_ADMIN" /> 
     <security:intercept-url pattern="/schedule/*" 
      access="ROLE_ADMIN" /> 


     <security:intercept-url pattern="/**" 
      access="ROLE_USER,ROLE_ADMIN" />  
    </security:http> 



    <security:authentication-manager id ="authenticationManager"> 
     <security:authentication-provider ref="customAuthenticationProvider"/> 
     <security:ldap-authentication-provider user-search-filter="(uid={0})" 
      group-search-base="ou=groups" group-search-filter="(uniqueMember={0})" 
      server-ref="ldapServer" user-context-mapper-ref="contextMapper" role-prefix="ROLE_" 
      group-role-attribute="cn"/> 
    </security:authentication-manager> 

    <security:ldap-server id="ldapServer" url="ldap://localhost:10389/dc=oreilly,dc=com" 
     manager-dn="uid=admin,ou=system" manager-password="secret"/> 

</beans> 

주 내가 그 안에 모두 인증 공급자와 하나에 두 개의 관리자를 합병했다. 그런 다음 하나의 요소에 <security:http /> 요소를 병합 했으므로 (더 이상 정규식이나 다른 패턴을 적용 할 필요가 없도록) 이제 <security:intercept-url /> 요소가 세 개 있습니다. 첫 번째 요소는 <security:http>이고 나머지 두 요소는 둘째.

+0

도움을 주셔서 감사합니다. 우리는 '보안 : http 요청 - matcher = "정규식"패턴 = "^/(약속) 일정 (/ (\ S) +) + $" 사용 표현식 = false "authentication-manager-ref ="LDAPAuth "> ... .. . '하지만 Auth-providers ..를 건너 뛰는 것 같습니다. customAuthenticationProvider를 전혀 사용하지 않고 있습니다 ... 다시 한번 귀하의 도움에 감사드립니다. – nocon