Seam IdentityStore NullpointerException для токена на базе запомнить меня - PullRequest
1 голос
/ 19 июля 2011

Я использую Seam 2.2.Final и следовал инструкциям главы 15.3.5.1. Проверка подлинности «Запомнить меня» на основе токенов.

<security:identity authenticate-method="#{authenticator.authenticate}" />
<security:remember-me enabled="true" mode="autoLogin" cookie-max-age="604800"/>
<security:jpa-token-store token-class="com.mydomain.AuthenticationToken" />
<event type="org.jboss.seam.security.notLoggedIn">
 <action execute="#{redirect.captureCurrentView}"/>
 <action execute="#{identity.tryLogin()}"/>
</event>
<event type="org.jboss.seam.security.loginSuccessful">
 <action execute="#{redirect.returnToCapturedView}"/>
</event>

Когда я захожу и проверяю «запомни меня», в базе данных создается новый токен. Но когда время сеанса истекло, и я пытаюсь вернуться, я получаю исключение NullPointerException

Caused by: java.lang.NullPointerException
at org.jboss.seam.security.management.IdentityManager.isUserEnabled(IdentityManager.java:130)
at org.jboss.seam.security.RememberMe$1.execute(RememberMe.java:306)
at org.jboss.seam.security.Identity.runAs(Identity.java:743)
at org.jboss.seam.security.RunAsOperation.run(RunAsOperation.java:75)

Когда identityStore инициализируется, identityStore становится пустым после этого вызова.

protected void initIdentityStore()
{    
  // Default to JpaIdentityStore
  if (identityStore == null)
  {
     identityStore = (IdentityStore) Component.getInstance(JpaIdentityStore.class, true);
}

Должен ли я настроить IdentityStore следующим образом

<security:jpa-identity-store
    user-class="com.domain.model.UserAccount"
    role-class="com.domain.model.UserRole"/>

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

ТНХ

РЕДАКТИРОВАТЬ: Это сообщение будет напечатано, где он должен найти метод. Он не содержится в карте фабрик в классе seam.core.Init.

if ( log.isTraceEnabled() ) log.trace("Seam component not found: " + name);

РЕДАКТИРОВАТЬ: ОК, похоже, мне нужно "установить" компонент в файле component.xml и переопределить JpaIdentityStore, по крайней мере, метод lookupUser до сих пор.

1 Ответ

1 голос
/ 22 июля 2011

Просто чтобы подвести итог проблем, с которыми я столкнулся.Документация в главе 15.3.5.1.покрывает только половину требуемых баллов.

  • RememberMe использует IdentityManager, который сам использует IdentityStore, который по умолчанию не включен.Так что <component class="org.jboss.seam.security.management.JpaIdentityStore"/> требуется.

  • Далее требуется JpaIdentityStore некоторая конфигурация, упомянутая в 15.4.2. Но мое имя пользователя не было частью объекта учетной записи (оно содержалось в списке вобъект учетной записи) и мои роли не были сущностью, а просто перечислением (хорошо, что можно было изменить).В любом случае я пропустил конфигурацию в 15.4.2 и переписал методы isUserEnabled () и getImpliedRoles.

  • Вы должны добавить Identity.tryLogin (), но с tryLogin () вход в систему без вывода сообщенийсрабатывает, что не вызывает событие LoginSuccessful.Чтобы вернуться на захваченную страницу.

.

<event type="org.jboss.seam.security.notLoggedIn">
 <action execute="#{redirect.captureCurrentView}"/>
 <action execute="#{identity.tryLogin()}"/>
</event>
<event type="org.jboss.seam.security.loginSuccessful">
 <action execute="#{redirect.returnToCapturedView}"/>
</event>

Я сделал свой собственный authenticator.tryLogin (), где я вызываю identity.tryLogin (), и после этого я запускаюсобытие loginSuccessful.Теперь проблема заключается в том, что все эти события происходят в одной строке, и оба элемента captureCurrentView и returnToCapturedView выполняют перенаправление, когда выполняется первое, поэтому я попадаю на страницу входа.

  • По умолчанию поведение RememberMe -аннулировать все токены пользователя, если его токен не существует.Таким образом, каждый может установить cookie с именем другого пользователя, чтобы сделать недействительным весь свой токен.

.

if (tokenStore.validateToken(decoded.getUsername(), decoded.getValue()))
        {
           credentials.setUsername(decoded.getUsername());
           credentials.setPassword(decoded.getValue());               
        }
        else
        {
           // Have we been compromised? Just in case, invalidate all authentication tokens
           tokenStore.invalidateAll(decoded.getUsername());
        }
...