Grails spring-security - Gerekli şifre değişikliğini kontrol etmek için başarı eyleminden önce müdahale edebilir miyim?

Sistemimde yeni kullanıcılar oluşturmaya başladığımda, onlara e-posta yoluyla geçici bir şifre gönderiyorum ve bir changePasswordNextLogin = true özelliği ayarlıyorum. İlk kez giriş yapmaya geldiklerinde, başarılı bir giriş üzerine akışı engellemek, bu değeri kontrol etmek ve doğruysa bunları bir şifre değiştirme eylemine yönlendirmek istiyorum. Şifre değişikliği tamamlandıktan sonra, ideal olarak onları hedeflerine göndermek istiyorum.

Varsayılan ayarlardan geçiyordum ve görmüyorum - ya da daha doğru bir şekilde yorumlamıyor - bunu gerçekleştirmenin herhangi bir yolu. Görünüşe göre, Grails'e bir çözüm getirmeye çalıştığım zaman, birisinin aynı şeyi yapmak için çok daha şık bir yaklaşım geliştirdiğini görüyorum. Buna izin verecek herhangi bir işlev var mı?

Değilse, bunu yapmak için en iyi yaklaşımla ilgili önerileri gerçekten takdir ediyorum.

1
İkiniz için üzgünüm. Yazının başlığında "Grails spring-security" yazanın yeterince açıklayıcı olduğunu düşünmüştüm ama S2'yi eklenti kullanmadan kullanmayı düşünmedim. Sanırım daha spesifik olmalıydım.
katma yazar Dave Shuck, kaynak
yay güvenlik çekirdek eklentisini mi kullanıyorsunuz? Ya da başka bir eklenti veya belki kendi filtreleriniz? Yay güvenlik eklentisini kullanıyorsanız, @darrend çerçeve tarafından sağlanan passwordExpired özelliğini kullanmak için temel sağladı.
katma yazar omarello, kaynak
@omarello soru metni s2 bahsetmedi, ama bu şekilde etiketlendi, bu yüzden güvenli bir varsayım olduğunu düşündüm :)
katma yazar darrend, kaynak

2 cevap

Spring Security ve grails eklentisi ile doğrudan bunun için bir miktar destek var, ama ayrıca kendiniz de biraz iş yapmak zorundasınız :)

Grails-spring-security eklentisini (ve S2Quickstart betiğini çalıştırdığınızda) yüklediğinizde oluşturulan etki alanı 'passwordExpired' adlı bir özelliğe sahiptir. Yeni kullanıcı alan adınızı oluşturduğunuzda bunu true olarak ayarlayın.

Kullanıcı ilk kez oturum açtığında, Spring Security çekirdek kitapçıkları, giriş denetleyicinizin authfail kapamasında yakalayabileceğiniz bir istisna atar ve bunları (kendinize sağlamanız gereken) değişiklik parola formuna yeniden yönlendirir.

İşte benim uygulamalarımdan bir örnek, bu kapanışın iskelet versiyonu zaten giriş kontrol cihazınıza dahil edilmelidir:

/**
 * 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' görünümünüzden, formu başka bir denetleyicinin kapatmasına geri gönderin (parolalar için istediğiniz kısıtlamaları kontrol eden ve güncelleştirilen parolayı etki alanı nesnesine kaydedecek olan 'updatePassword' olarak adlandırıyorum).

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: '/'
}
5
katma
Bu tam olarak aradığım şey gibi görünüyor. Açıklamak için zaman ayırdığınız için gerçekten minnettarım. Mantıklı gelir!
katma yazar Dave Shuck, kaynak

Spring Secuirty 3.0 ve sonraki sürümlerini kullanıyorsanız, yay güvenlik eklenti belgelerine başvurabilirsiniz 11.3 Hesap Kilitleme ve Parola Değişikliğini Zorlama . Ayarlamanız gerektiğini unutmayın Config.groovy'de grails.plugin.springsecurity.apf.storeLastUsername = true .

1
katma