Существует некоторая поддержка для этого непосредственно с Spring Security и плагином grails, но вам также нужно выполнить некоторую работу самостоятельно:)
Класс домена, который был создан при установке плагина grails-spring-security(и запустил скрипт S2Quickstart) имеет свойство с именем 'passwordExpired'.Установите это значение true при создании нового экземпляра домена пользователя.
Как только этот пользователь войдет в систему в первый раз, основные библиотеки Spring Security сгенерируют исключение, которое вы можете поймать при закрытии authfail контроллера входа, повторно-направив их в форму смены пароля (которую вы должны указать самостоятельно).
Вот пример из одного из моих приложений, скелетная версия этого закрытия уже должна быть включена в ваш контроллер входа в систему:
/**
* Callback after a failed login.
*/
def authfail = {
def msg = ''
def username =
session[UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY]
def exception = session[WebAttributes.AUTHENTICATION_EXCEPTION]
if (exception) {
if (exception instanceof CredentialsExpiredException) {
msg = g.message(code: "springSecurity.errors.login.passwordExpired")
if (!springSecurityService.isAjax(request))
redirect (action:'changePassword') // <-- see below
}
// other failure checks omitted
}
if (springSecurityService.isAjax(request)) {
render([error: msg] as JSON)
}
else {
flash.message = msg
redirect controller: 'login', action:'auth', params: params
}
}
/**
* render the change pwd form
*/
def changePassword = {
[username: session[UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY] ?: springSecurityService.authentication.name]
}
Из представления «changePasssword» отправьте форму обратно на закрытие другого контроллера (я называю мой «updatePassword», который проверяет любые ограничения, которые вы хотите для паролей, и либо сохраняет обновленный пароль на объекте домена, либо нет).
def updatePassword = {
String username = session[UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY] ?: springSecurityService.authentication.name
if (!username) {
flash.message = 'Sorry, an error has occurred'
redirect controller: 'login', action:'auth'
return
}
String password = params.password
String newPassword = params.password_new
String newPassword2 = params.password_new_2
if (!password || !newPassword || !newPassword2 || newPassword != newPassword2) {
flash.message = 'Please enter your current password and a new password'
render view: 'changePassword', model: [username: username]
return
}
SecUser user = SecUser.findByUsername(username)
if (!passwordEncoder.isPasswordValid(user.password, password, null /*salt*/)) {
flash.message = 'Current password is incorrect'
render view: 'changePassword', model: [username: username]
return
}
if (passwordEncoder.isPasswordValid(user.password, newPassword, null /*salt*/)) {
flash.message = 'Please choose a different password from your current one'
render view: 'changePassword', model: [username: username]
return
}
if (!newPassword.matches(PASSWORD_REGEX)) {
flash.message = 'Password does not meet minimum requirements'
render view: 'changePassword', model: [username: username]
return
}
// success if we reach here!
user.password = springSecurityService.encodePassword(newPassword)
user.passwordExpired = false
user.save()
flash.message = 'Password changed successfully' + (springSecurityService.loggedIn ? '' : ', you can now login')
redirect uri: '/'
}