2013-01-13 1 views
13

Ich habe Change-Password-Funktionalität mit Spring-Sicherheit implementiert, aber ((UserDetails Principal) .getPassword()) gibt null für angemeldete Benutzer zurück.UserDetails getPassword gibt im Frühling Sicherheit null zurück 3.1. Wie bekomme ich das Passwort des aktuell angemeldeten Benutzers?

Wenn ich mich richtig erinnere, arbeitete dies früher in 3.0. Wurde dies in 3.1 geändert, damit das aktuelle Passwort des angemeldeten Benutzers nicht abgerufen werden kann?

Im folgenden Code überprüfe ich das aktuelle Passwort in das Benutzerpasswort von der Webseite eingegeben. Ich überprüfe dann, ob das Passwort des angemeldeten Benutzers mit dem eingegebenen Passwort übereinstimmt. Wenn dies der Fall ist, möchte ich oldPasswordMatchNewPassword = true festlegen.

Wie implementiere ich diese Funktionalität?

@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; 
    } 
} 

Ich habe ein paar sysout() s, so dass ich die zurückgegebenen Werte sehen kann. For ((UserDetails Principal) .getUsername() Ich kann den korrekten angemeldeten Benutzer sehen. ((UserDetails Principal) .getPassword() es gibt null zurück.

Wie bekomme ich ((UserDetails Principal) .getPassword() diesen Wert?

Vielen Dank im Voraus!

Antwort

25

Ich habe diesen Code-Block (erase-credentials = "false") verwendet, um dies zu beheben. Ich weiß nicht, ob dies eine elegante Lösung, aber es feste mein Problem:

<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

Ja, dies hat sich in Version 3.1 geändert. Anmeldeinformationen werden nach einer erfolgreichen Authentifizierung standardmäßig gelöscht. Sie können eraseCredentialsAfterAuthentication auf ProviderManager auf false setzen, um dies zu verhindern. Details siehe hier: http://static.springsource.org/spring-security/site/docs/3.2.x/reference/core-services.html#core-services-erasing-credentials

+0

Das macht Sinn. Was ist die beste Vorgehensweise dafür? Ich möchte "eraseCredentialsAfterAuthentication" nicht deaktivieren, da dies ein Sicherheitsrisiko darstellen kann. Kannst du mir helfen, das herauszufinden? – texasdude11

2

Da das Passwort nicht im Speicher gehalten wird, nachdem der Benutzer (in der Regel eine gute Sache) authentifiziert wurde, müßten Sie ausdrücklich laden Sie es neu, um es zu benutzen. Eine alternative und flexiblere Strategie ist eine Instanz der AuthenticationManager und verwendet, die direkt zu injizieren:

Sie nicht über Dinge wie Passwort-Codierung Strategien
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 
} 

auf diese Weise zu kümmern. Beachten Sie, dass Sie keine Passwörter im Klartext speichern sollten. Sie sollten mit bcrypt or something similar gehashed werden.