2009-05-27 1 views
3

Я пишу веб-приложение в Grails с плагином Acegi/Spring Security, и у меня возникают проблемы с его отображением изменений, которые я делаю для экземпляров пользователя , Я работаю только с Groovy/Grails около трех недель, поэтому, пожалуйста, простите меня, если эта проблема тривиальна, так как я просматриваю списки рассылки и учебные пособия, пытаясь найти ответ.Acegi/Spring Security Графический плагин не видит изменений в экземпляре пользователя

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

Вот соответствующий отрывок из UserController.update():

def person = User.get(params.id) 
//...snip error checking... 

//Update user attributes 
person.username = params.email 
person.email = params.email 
person.userRealName = params.userRealName 

//Attempt to save changes 
if (person.save()) { 
    //If successful, redirect back to profile viewing page 
    redirect action: show, id: person.id 
    return 
} 
else { 
    //Otherwise, show errors and edit again 
    render view: 'edit', model: buildPersonModel(person) 
    return 
} 

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

loggedInUserInfo(field:'realName') 

Но это делает:

User.get(loggedInUserInfo(field:'id').toLong()).realName 

Новая информация иногда появляется после того, как я выйти и снова, но обычно это не делает, часто не появляется даже после трех или более релогов. Кроме того, я попытался добавить «flush: true» к person.save() без эффекта.

(Peripheral вопрос: это плохо для меня, чтобы быть возился с классом пользователей, как это Если нет, то самый лучший способ, чтобы добавить информацию к нему?)

Update после более расследования: It похоже, если я использую loggedInUserInfo() на обычной странице, он отлично работает, но если я использую его внутри макета, он демонстрирует поведение, которое я описал. Может ли быть какое-то странное кэширование?

ответ

2

У меня есть обходной путь для этой проблемы, и я также создал запись JIRA.

Возможно, ошибка в том, как Acegi обновляет ее пользователей внутри страны. Я предоставляю обходной путь в виде фильтра grails, который обновляет полномочия пользователя вручную каждый раз, когда к контроллеру обращаются. Не идеальный, но он работает.

Cheers,

+0

Спасибо за ссылку. Не могли бы вы привести пример того, как написать такой фильтр? Я больше не работаю над проектом, у которого есть проблема, но я уверен, что кто-то еще мог бы это увидеть. –

+0

уверенный вещь. Руководство по фильтрам Grails находится здесь: http://www.grails.org/Filters, но короткая версия - это то, что вам просто нужно поместить этот файл фильтра в каталог grails-app/conf, и он работает. Cheers – sinjax

+0

+1 - У меня была такая же проблема с ролями, и обходной фильтр, предоставленный в JIRA, решил проблему. –

2

Вы запустили grails generate-manager после изменения вашего пользовательского класса?

+0

Нет, я этого не сделал, и понятия не имел, что мне нужно. Спасибо! Я не могу проверить это до понедельника, поэтому я буду ждать пару дней, прежде чем я скажу, является ли это решением или нет. –

+0

Я не знал ни о 3 месяца назад. Но на http://www.infoq.com/articles/grails-acegi-integration я нашел ответ в комментарии «Как добавить новые поля в AuthUser/User? Почему 2 типа пользователей?» Это решило мою проблему. –

+0

Извините, но это не исправляет. Проблема сохраняется. И все же спасибо за ссылку. Я подозреваю, что это связано с тем, что данные кэшируются в сеансах, но я не уверен. –

1

Acegi caches Информация о пользователе, если я правильно помню. Проверьте файл 'DefaultSecurityConfig' (я думаю, это имя, в config /) для отключения кеша информации пользователя. Вы также можете вызвать метод authenticateService (не помню, какой метод прямо сейчас), чтобы вырезать кеш пользователя.

Возможно, вы сможете найти последнее в закрытии UserController#update.

+0

К сожалению, установка cacheUsers = false не устраняет проблему. Кроме того, я не смог найти метод, чтобы вырезать кеш пользователя в authenticateService. –

1

Я столкнулся с такой же проблемой и последовал совету, предоставленному Максимилианом Швейцером выше. Вначале это не сработало.

Дайте эти шаги попробовать и посмотреть, если это решает проблему:

  1. Я выбежала генерировать-менеджер, как в ответ выше Максимилиан Швейцер.
  2. Пытался войти с пользователями, созданных до Я побежал генерировать-менеджер - Не работает
  3. Я создал нового пользователя (с новым UserController, GSP и т.д.)
  4. Пытался войти в систему с новым пользователем работает просто отлично.
  5. Удалены старые пользователи, созданные до и воссоздали их. Он работал нормально.

Хотя не уверен, что это относится к вашей ситуации.

HTH!

+0

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

1

У меня была такая же проблема. Мое решение состояло в том, чтобы обновить плагин acegi до версии 0.5.1 (acegi 0.5.1 - Grails Spring Security 2.0 Plugin).

Тогда я поставил на /plugins/acegi-0.5.1/grails-app/conf/DefaultSecurityConfig.groovy

cacheUsers = false 

и теперь вуаля! это работает!

Luis

0

Необходимо выполнить сброс аутентифицированного пользователя. Код ниже делает именно это (от this blog).

import org.springframework.security.context.SecurityContextHolder 
import org.springframework.security.providers.UsernamePasswordAuthenticationToken 
import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUserImpl 
import org.springframework.security.GrantedAuthority 
import org.springframework.security.GrantedAuthorityImpl 

... 

def refreshAuthenticatedUser(user) { 
    GrantedAuthority[] auths = user.authorities.collect { 
     new GrantedAuthorityImpl(it.authority) 
    } 
    def grailsUser = new GrailsUserImpl(
      user.username, 
      "", 
      user.enabled, 
      true, 
      true, 
      true, 
      auths, 
      user) 
    def authToken = new UsernamePasswordAuthenticationToken(grailsUser, '', auths) 
    SecurityContextHolder.context.authentication = authToken 

} 
Смежные вопросы