【问题标题】:Conflicting beans of userDetailsServiceuserDetailsS​​ervice 的冲突 bean
【发布时间】:2015-03-17 15:24:16
【问题描述】:

我正在使用 spring-security 开发 Spring-MVC 应用程序,我有 2 种不同类型的用户可以登录,一种来自个人帐户,一种是组帐户。 所以基本上我想要2个daoAuthenticationMethods。 对于这两者,我都实现了 UserDetails 和 userDetailsS​​ervice 接口。在参考this 上的帖子后,我正在尝试实施这种方法。 我得到的错误是服务层中的 userDetailsS​​ervice 冲突。我知道我不能使用 2 userDetailsS​​ervice,但是如果我在 xml 的属性选项卡中添加其他内容,我会收到未知属性错误。请检查配置,请告诉我我可能做错了什么。

错误日志:

Offending resource: ServletContext resource [/WEB-INF/spring/appServlet/security-applicationContext.xml]; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/spring/appServlet/servlet-context.xml]; nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'userDetailsService' for bean class [com.journaldev.spring.service.GroupLoginServiceImpl] conflicts with existing, non-compatible bean definition of same name and class [com.journaldev.spring.service.LoginServiceImpl]
    at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:70)
    at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85)

安全应用程序上下文.xml:

<!-- Global Security settings -->
<security:global-method-security pre-post-annotations="enabled" />
<security:http create-session="ifRequired" use-expressions="true" auto-config="true" disable-url-rewriting="true">
    <security:form-login login-page="/" default-target-url="/canvas/list"
                         always-use-default-target="false"  authentication-failure-url="/denied.jsp" />

<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
    <security:filter-chain-map path-type="ant">
        <security:filter-chain pattern="/**" filters="authenticationProcessingFilterForPersonal, authenticationProcessingFilterForGroup"/>
    </security:filter-chain-map>
</bean>

<bean id="authenticationProcessingFilterForPersonal"
      class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
    <property name="authenticationManager" ref="authenticationManagerForPersonal"/>
    <property name="filterProcessesUrl" value="/j_spring_security_check_for_person" />

</bean>

<bean id="authenticationProcessingFilterForGroup"
      class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
    <property name="authenticationManager" ref="authenticationManagerForGroup"/>
    <property name="filterProcessesUrl" value="/j_spring_security_check_for_group"/>
</bean>


<bean id="authenticationManagerForPersonal" class="org.springframework.security.authentication.ProviderManager">

<property name="providers">
        <list>
            <bean class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
                <property name="userDetailsService">
                    <ref bean="LoginServiceImpl"/>
                </property>
                <property name="passwordEncoder" ref="encoder"/>
            </bean>
        </list>
    </property>
</bean>

<bean id="authenticationManagerForGroup" class="org.springframework.security.authentication.ProviderManager">
    <property name="providers">
        <list>
            <bean class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
                <property name="userDetailsService">
                    <ref bean="GroupLoginServiceImpl"/>
                </property>
                <property name="passwordEncoder" ref="encoder"/>
            </bean>
        </list>
    </property>
</bean>


<security:authentication-manager alias="authenticationManager">
    <security:authentication-provider ref="authenticationManagerForPersonal"/>
    <security:authentication-provider ref="authenticationManagerForGroup"/>
</security:authentication-manager>

<beans:bean id="encoder"
            class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
    <beans:constructor-arg name="strength" value="11" />
</beans:bean>

登录服务实现:

// This method is for the personalAccount
@Transactional
@Service("userDetailsService")
public class LoginServiceImpl implements UserDetailsService{

    @Autowired private PersonDAO personDAO;
    @Autowired private Assembler assembler;

    private static final GrantedAuthority USER_AUTH = new SimpleGrantedAuthority("ROLE_USER");

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException,DataAccessException {
        Person person = personDAO.findPersonByUsername(username.toLowerCase());
            if(person == null) { throw new UsernameNotFoundException("Wrong username or password");} 
        return assembler.buildUserFromUserEntity(person);
    }
}

GroupLoginServiceImpl :

@Transactional
@Service("userDetailsService")  // I cannot change this, it throws me error when I change this or remove this
public class GroupLoginServiceImpl implements UserDetailsService {

    @Autowired
    private GroupMembersDAO groupMembersDAO;

    @Autowired
    private GroupAssembler groupAssembler;

    private static final GrantedAuthority USER_AUTH = new SimpleGrantedAuthority("ROLE_GROUP");

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException,DataAccessException {
        GroupMembers groupMembers = groupMembersDAO.findMemberByUsername(username.toLowerCase());
        if(groupMembers == null) { throw new UsernameNotFoundException("Wrong username or password");} 
        return groupAssembler.buildUserFromUserEntity(groupMembers);
    }
}

如有必要,我也可以发布任何其他方法。请让我知道该怎么做。欢迎任何指点。谢谢。

【问题讨论】:

  • 两个服务不应具有相同的名称。在GroupLoginServiceImpl 上设置不同的名称会引发什么错误?
  • @holmis83 我已在主帖中添加了最新的错误日志,请查看。谢谢。

标签: spring spring-mvc spring-security


【解决方案1】:

我认为您误解了如何编写 XML。第一个实例应该是这样的:

<property name="userDetailsService" ref="userDetailsService">

第二个:

<property name="userDetailsService" ref="groupDetailsService">

【讨论】:

  • 我已经尝试过您所说的,错误日志在主帖中,其中包含您建议的更改。我也在 GroupServiceLoginImpl 中添加了 groupDetailsS​​ervice。请看一看。
  • @WeareBorg 不同的问题,您有三个身份验证管理器!清理。
  • 我只有一个全局的authenticationManager,其他的只是bean。
  • @WeareBorg 安全命名空间是定义 bean 的简写。因此,身份验证管理器元素 = 身份验证管理器 bean。
  • 好的,当你这么说的时候,我确实试过用 和它下面的 authenticationProvider 删除代码块。当我这样做时,我收到一个错误 No bean named 'org.springframework.security.authenticationManager' is defined ??您能帮我澄清一下我必须在 security-application-context.xml 中更改的内容吗?谢谢。
猜你喜欢
  • 2020-02-28
  • 1970-01-01
  • 1970-01-01
  • 2012-06-11
  • 2017-08-17
  • 2013-05-12
  • 2020-06-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多