2013-03-29 4 views
3

Я боролся с аутентификацией настроек аутентификации с помощью сиро 1.2.1 в веб-приложении с весной. У меня 2 сферы. Один аутентифицируется против database и один против ldap. оба realms работают отлично, так что я хотел FirstSuccessfulStrategy, но кажется, что оба царства все еще вызываются. вот мой контекст безопасности-приложения:apache shiro: как установить аутентификациюStrategy с использованием Spring applicationcontext?

<bean id="passwordService" class="org.apache.shiro.authc.credential.DefaultPasswordService"> 
    <property name="hashService" ref="hashService" /> 

</bean> 

<bean id="hashService" class="org.apache.shiro.crypto.hash.DefaultHashService"> 
    <property name="hashAlgorithmName" value="SHA-512" /> 
    <property name="hashIterations" value="500000" /> 
</bean> 


<bean id="SaltedSha512JPARealm" class="bla.bla.webapp.security.SaltedSha512JPARealm"> 
    <property name="credentialsMatcher"> 
     <bean class="org.apache.shiro.authc.credential.PasswordMatcher"> 
      <property name="passwordService" ref="passwordService"/> 
     </bean> 
    </property> 

</bean> 


<bean id="ldapContextFactory" class="org.apache.shiro.realm.ldap.JndiLdapContextFactory"> 
    <property name="url" value="${user.ldap.connection.url}"/> 
    <property name="authenticationMechanism" value="${user.ldap.connection.auth_mecanism}"/> 
</bean> 

<bean id="ldapRealm" class="bla.bla.webapp.security.LDAPRealm"> 
    <property name="userDnTemplate" value="${user.ldap.connection.userDnTemplate}"/> 
    <property name="contextFactory" ref="ldapContextFactory" /> 

</bean> 

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager" depends-on="roleRepository,roleRightRepository,rightRepository,userRepository"> 

    <property name="realms"> 
     <list> 
      <ref local="ldapRealm"/> 
      <ref local="SaltedSha512JPARealm"/> 
     </list> 
    </property> 
    <property name="authenticator.authenticationStrategy"> 
     <bean class="org.apache.shiro.authc.pam.FirstSuccessfulStrategy"/> 
    </property> 

</bean> 

есть что-нибудь там, что я плохо себя чувствую?

ответ

2

FirstSuccessfulStrategy означает, что ваш аутентификатор попробует все ваши сферы для аутентификации пользователя до первого успешного завершения. Ваши настройки были настроены по порядку: ldapRealm, SaltedSha512JPARealm. Так что если lapRealm не получится, аутентификатор попробует второй. Чтобы решить эту проблему, вы можете попытаться настроить наиболее успешную или самую быструю область, чтобы быть первыми, например. Вы можете изменить ваш заказ царств быть SaltedSha512JPARealm, ldapRealm:

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager" depends-on="roleRepository,roleRightRepository,rightRepository,userRepository"> 

    <property name="realms"> 
     <list> 
      <ref local="SaltedSha512JPARealm"/> 
      <ref local="ldapRealm"/> 
     </list> 
    </property> 
    <property name="authenticator.authenticationStrategy"> 
     <bean class="org.apache.shiro.authc.pam.FirstSuccessfulStrategy"/> 
    </property> 

</bean> 

Но вы должны понимать, что для данной конфигурации, если SaltedSha512JPARealm потерпит неудачу, аутентификатор будет пытаться ldapRealm.

Или вы можете попробовать использовать разные классы токенов для этих областей. Но он будет работать, только если у вас есть разные точки входа для аутентификации для каждого из них.

UPD

кажется, что ModularRealmAuthenticator устроен так, что он всегда будет пытаться идентифицировать пользователя всеми сферами. FirstSuccessfulStrategy может влиять только на результат аутентификации. Он вернется первым успешно AuthenticationInfo. Для достижения своей цели вам необходимо переопределить метод ModularRealmAuthenticator#doMultiRealmAuthentication. Это может выглядеть следующим образом:

protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) { 
    AuthenticationStrategy strategy = getAuthenticationStrategy(); 
    AuthenticationInfo aggregate = strategy.beforeAllAttempts(realms, token); 
    if (log.isTraceEnabled()) { 
     log.trace("Iterating through {} realms for PAM authentication", realms.size()); 
    } 
    for (Realm realm : realms) { 
     aggregate = strategy.beforeAttempt(realm, token, aggregate); 
     if (realm.supports(token)) { 
      log.trace("Attempting to authenticate token [{}] using realm [{}]", token, realm); 
      AuthenticationInfo info = null; 
      Throwable t = null; 
      try { 
       info = realm.getAuthenticationInfo(token); 
      } catch (Throwable throwable) { 
       t = throwable; 
       if (log.isDebugEnabled()) { 
        String msg = "Realm [" + realm + "] threw an exception during a multi-realm authentication attempt:"; 
        log.debug(msg, t); 
       } 
      } 
      aggregate = strategy.afterAttempt(realm, token, info, aggregate, t); 
      // dirty dirty hack 
      if (aggregate != null && !CollectionUtils.isEmpty(aggregate.getPrincipals())) { 
       return aggregate; 
      } 
      // end dirty dirty hack 
     } else { 
      log.debug("Realm [{}] does not support token {}. Skipping realm.", realm, token); 
     } 
    } 
    aggregate = strategy.afterAllAttempts(token, aggregate); 
    return aggregate; 
} 
+0

спасибо за ваш ответ. Моя проблема заключается в том, что даже после успешной проверки подлинности с помощью 'stuart ldap server' (http://blog.stuartlewis.com/2008/07/07/test-ldap-service/) он пытается аутентифицироваться в базе данных с помощью' SaltedSha512JPARealm' , Вот почему я, хотя что-то не так с моей конфигурацией. Знание ldapRealm было добавлено сначала, это не должно произойти правильно? –

+0

Вы правы. Кажется, что 'ModularRealmAuthenticator' спроектирован так, что он всегда будет пытаться аутентифицировать пользователя по всем областям. Только обновленный ответ. – sody

+0

Привет, извините за поздний ответ. я пробовал использовать другой токен и создавать их на основе combobox, который я накладываю на пользовательский интерфейс, точно так же, как и для входа в MS windows для переключения домена. Это мое быстрое решение. Я попробую это решение на следующей итерации, я поймаю крайний срок. так что исправление отлично работает для парня и руководства пользователя. –

0
<property name="authenticator.authenticationStrategy"> 
    <bean class="org.apache.shiro.authc.pam.FirstSuccessfulStrategy"/> 
</property> 

приведенное выше определение является неправильным. Определим его следующим образом

<property name="authenticator.authenticationStrategy" ref="authcStrategy"/> 

И определим ниже определение бина отдельно

<bean id="authcStrategy"  class="org.apache.shiro.authc.pam.FirstSuccessfulStrategy"/> 

Тогда он будет работать, как и ожидалось