2013-01-13 19 views
13

Yay güvenliği kullanarak değişiklik parola işlevselliği uyguladım ama ((UserDetails) ana) .getPassword()), oturum açmış kullanıcı için null döndürüyor.UserDetails getPassword, spring security 3.1'de null değerini döndürür. Şu anda oturum açmış kullanıcının şifresi nasıl alınır?

Doğru hatırlıyorsam, bu daha önce 3.0'da çalışıyordu. Bu, 3.1'de değiştirildi, böylece oturum açmış kullanıcının geçerli şifresi alınamaz mı?

Aşağıdaki kodda, web sayfasından kullanıcı şifresine yazılan mevcut şifreyi kontrol ediyorum. Sonra oturum açmış olan kullanıcının şifresinin şifre ile yazılanların eşleşip eşleşmediğini kontrol ediyorum. Eğer yaparsa o zaman oldPasswordMatchNewPassword = true değerini ayarlamak istiyorum.

Bu işlevi nasıl uygularım?

@RequestMapping(value = "/account/changePassword.do", method = RequestMethod.POST) 
    public String submitChangePasswordPage(
      @RequestParam("oldpassword") String oldPassword, 
      @RequestParam("password") String newPassword) { 
     Object principal = SecurityContextHolder.getContext() 
       .getAuthentication().getPrincipal(); 
     String username = principal.toString(); 
     if (principal instanceof UserDetails) { 
      username = ((UserDetails) principal).getUsername(); 
      System.out.println("username: " + username); 
      System.out.println("password: " 
        + ((UserDetails) principal).getPassword()); 
      if (((UserDetails) principal).getPassword() != null) { 
       if (((UserDetails) principal).getPassword().equals(oldPassword)) { 
        oldPasswordMatchNewPassword = true; 
       } 
      } 
     } 
    if (oldPasswordMatchNewPassword == true) { 
     logger.info("Old password matches new password. Password will be updated."); 
     changePasswordDao.changePassword(username, newPassword); 
     SecurityContextHolder.clearContext(); 
     return "redirect:home.do"; 
    } else { 
     logger.info("Old password did not match new password. Password will be not be updated."); 
     return null; 
    } 
} 

Döndürülen değerleri görebilmek için birkaç tane sysout() koydum. For ((UserDetails) principal) .getUsername() Doğru oturum açmış kullanıcıyı görebilirim. ((UserDetails) principal) .getPassword() null döndürüyor.

Nasıl ((UserDetails) principal) .getPassword() bu değeri alırım?

Şimdiden teşekkürler!

cevap

25

Bunu düzeltmek için bu kod bloğunu kullandım (erase-credentials = "false"). , Açıkça gerekir kullanıcı (genellikle iyi bir şey) doğrulandıktan sonra şifre hafızasında muhafaza olmadığından

<authentication-manager alias="authenticationManager" erase-credentials="false"> 
    <!-- authentication-provider user-service-ref="userService" --> 
    <authentication-provider> 
     <jdbc-user-service data-source-ref="dataSource" /> 
    </authentication-provider> 
</authentication-manager> 
6

Evet, bu sürüm 3.1 de değişti. Kimlik bilgileri, varsayılan olarak başarılı bir kimlik doğrulamasından sonra temizlenir. Bunu önlemek için eraseCredentialsAfterAuthentication ayarını ProviderManager üzerinde yanlış olarak ayarlayabilirsiniz. Buraya bakın: http://static.springsource.org/spring-security/site/docs/3.2.x/reference/core-services.html#core-services-erasing-credentials

+0

Bu mantıklı. Peki bunu yapmak için en iyi uygulama nedir? Güvenlik riski oluşturabileceği için silmeCredentialsAfterAuthentication öğesini kapatmak istemiyorum. Bunu anlamak için bana yardım edebilir misin? – texasdude11

2

: Bu hoş bir çözüm olup olmadığını bilmiyorum ama benim sorun sabit Kullanmak için yeniden yükleyin.

String name = SecurityContextHolder.getContext().getAuthentication(); 

try { 
    authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(name, oldPassword)); 
    // Update password here with your dao 
} catch (AuthenticationException e) { 
    // Old password was wrong 
} 

şifre kodlama stratejileri gibi şeyler hakkında endişelenmenize gerek yok bu şekilde: Alternatif ve daha esnek bir strateji AuthenticationManager bir örneğini enjekte ve doğrudan bu kullanmaktır. Parolaları düz metin olarak saklamamanız gerektiğini unutmayın. bcrypt or something similar'u kullanmalıdırlar.

İlgili konular