我正在开发一个使用Spring,Vaadin和Apache Shiro进行身份验证和授权的Web应用程序 . 我有两个领域,因为一些用户通过数据库登录,其他用户通过LDAP进行身份验证 . JDBC领域工作得很完美,但不管怎样,LDAP领域都允许每个人通过 - 无论提供什么用户名/密码组合 .

这是我的Spring配置:

<!-- Apache Shiro -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager" />
</bean>

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realms">
        <list>
            <ref bean="jdbcRealm" />
            <ref bean="ldapRealm" />
        </list>
    </property>
    <property name="authenticator.authenticationStrategy">
        <bean class="org.apache.shiro.authc.pam.FirstSuccessfulStrategy" />
    </property>
</bean>
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

<bean id="ldapContextFactory" class="org.apache.shiro.realm.ldap.JndiLdapContextFactory">
    <property name="url" value="ldap://localhost:389" />        
</bean>

<bean id="jdbcRealm" class="org.apache.shiro.realm.jdbc.JdbcRealm">
    <property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="ldapRealm" class="org.apache.shiro.realm.ldap.JndiLdapRealm">
    <property name="contextFactory" ref="ldapContextFactory" />
    <property name="userDnTemplate" value="uid={0},ou=people,dc=maxcrc,dc=com" />
</bean>

登录相当典型:

try {

    // Obtain user reference
    Subject currentUser = SecurityUtils.getSubject();   

    // Create token using provided username and password
    UsernamePasswordToken token = new UsernamePasswordToken(userName, password);

    // Remember user
    if(rememberMe.getValue())
        token.setRememberMe(true);

    // Login
    currentUser.login(token);

    // If we are here, no exception was raised and the user was logged in, so redirect
    UI.getCurrent().getNavigator().navigateTo("main" + "/" + "main-page");

    // Fire CustomEvent
    fireEvent(new CustomEvent(ErasmusLoginForm.this));

} catch ( UnknownAccountException e ) {
    Notification.show("No such user...");
} catch ( IncorrectCredentialsException e ) {
    Notification.show("Invalid creditentials...");
} catch ( LockedAccountException e ) {
    Notification.show("Locked account...");
} catch ( AuthenticationException e ) {
    e.printStackTrace();
    Notification.show("Some other exception...");
} catch (Exception e) {
    // Password encryption exception
}

我几乎无处可读,没有运气 . 这篇文章(Shiro Authenticates Non-existent User in LDAP)对我没有帮助 - DN模板和URL都是正确的,服务器(LDAP服务器)正在运行 . 为什么它让每个人都通过?

如果我关闭Ldap领域,JDBC身份验证将完美运行 . 但是随着他们两个开启,每个人都可以通过,因为我使用的是FirstSuccessfulStrategy .

编辑:附加说明:如果我提供一个空密码,则引发AuthenticationException . 但任何非空密码都可以正常工作 .

有任何想法吗?