How does PasswordEncoder get called in Spring Security? -


i'm experimenting spring boot (1.0.0, using boot web , security), , have working web application secured endpoints authenticated user so. code works (configure httpsecurity omitted brevity) requiring username / password http requests endpoints:

@enableglobalmethodsecurity(prepostenabled = true) @configuration public class securityconfiguration extends websecurityconfigureradapter {  @inject public void configureglobal(authenticationmanagerbuilder auth) throws exception {     auth.inmemoryauthentication().withuser("user").password("password").roles("user"); } 

in preparation using spring security users database, put security pieces in way think should work, notably without database @ all. purely experiment security related classes.

so above code used configure authenticationmanagerbuilder changed this:

// private test implementations can explore security without database // here usernames , passwords valid // org.springframework.security.crypto.password.passwordencoder @bean public passwordencoder passwordencoder() {     return new passwordencoder() {         @override public string encode(charsequence cs) {             return cs.tostring();         }         @override public boolean matches(charsequence cs, string string) {             return true;         }     }; }  @bean public userdetailsservice createuserdetailsservice() {     return new userdetailsservice() {         @override         public userdetails loaduserbyusername(string string) throws usernamenotfoundexception {             return new user(); // trivial implementation of userdetails         }     }; }  @bean @inject public daoauthenticationprovider createdaoauthenticationprovider(userdetailsservice service, passwordencoder encoder) {     daoauthenticationprovider provider = new daoauthenticationprovider();     provider.setuserdetailsservice(service);     provider.setpasswordencoder(encoder);     return provider; }  @bean @inject public authenticationmanager authenticationmanager(authenticationprovider provider) throws exception {     // includes trivial implementation of objectpostprocessor     return new authenticationmanagerbuilder(new noppostprocessor())             .authenticationprovider(provider)             .build(); } 

my custom user details service called custom password encoder never called, verified setting breakpoints @ appropriate lines. , authentication fails.

how password encoder called? shouldn't called authentication of every http request? should expect called above configuration?

the authenticate method of abstractuserdetailsauthenticationprovider ( extended daoauthenticationprovider) this

public authentication authenticate(authentication authentication) throws authenticationexception {         assert.isinstanceof(usernamepasswordauthenticationtoken.class, authentication,             messages.getmessage("abstractuserdetailsauthenticationprovider.onlysupports",                 "only usernamepasswordauthenticationtoken supported"));          // determine username         string username = (authentication.getprincipal() == null) ? "none_provided" : authentication.getname();          boolean cachewasused = true;         userdetails user = this.usercache.getuserfromcache(username);          if (user == null) {             cachewasused = false;              try {                 user = retrieveuser(username, (usernamepasswordauthenticationtoken) authentication);             } catch (usernamenotfoundexception notfound) {                 logger.debug("user '" + username + "' not found");                  if (hideusernotfoundexceptions) {                     throw new badcredentialsexception(messages.getmessage(                             "abstractuserdetailsauthenticationprovider.badcredentials", "bad credentials"));                 } else {                     throw notfound;                 }             }              assert.notnull(user, "retrieveuser returned null - violation of interface contract");         }          try {             preauthenticationchecks.check(user);             additionalauthenticationchecks(user, (usernamepasswordauthenticationtoken) authentication);         } catch (authenticationexception exception) {             if (cachewasused) {                 // there problem, try again after checking                 // we're using latest data (i.e. not cache)                 cachewasused = false;                 user = retrieveuser(username, (usernamepasswordauthenticationtoken) authentication);                 preauthenticationchecks.check(user);                 additionalauthenticationchecks(user, (usernamepasswordauthenticationtoken) authentication);             } else {                 throw exception;             }         }          postauthenticationchecks.check(user);          if (!cachewasused) {             this.usercache.putuserincache(user);         }          object principaltoreturn = user;          if (forceprincipalasstring) {             principaltoreturn = user.getusername();         }          return createsuccessauthentication(principaltoreturn, authentication, user);     } 

as can see after user loaded , confirmed present in repository, there call additionalauthenticationchecks.if user not found additional check not done. in additionalcheck method password encoder used. here implementation in daauthenticationprovider

 @suppresswarnings("deprecation")     protected void additionalauthenticationchecks(userdetails userdetails,             usernamepasswordauthenticationtoken authentication) throws authenticationexception {         object salt = null;          if (this.saltsource != null) {             salt = this.saltsource.getsalt(userdetails);         }          if (authentication.getcredentials() == null) {             logger.debug("authentication failed: no credentials provided");              throw new badcredentialsexception(messages.getmessage(                     "abstractuserdetailsauthenticationprovider.badcredentials", "bad credentials"), userdetails);         }          string presentedpassword = authentication.getcredentials().tostring();          if (!passwordencoder.ispasswordvalid(userdetails.getpassword(), presentedpassword, salt)) {             logger.debug("authentication failed: password not match stored value");              throw new badcredentialsexception(messages.getmessage(                     "abstractuserdetailsauthenticationprovider.badcredentials", "bad credentials"), userdetails);         }     } 

as can see password encoder used match password presented stored in repository. if password encoder not being called, 1 probable reason user not found.


Comments

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

inno setup - TLabel or TNewStaticText - change .Font.Style on Focus like Cursor changes with .Cursor -