====== Create a user programmatically in Spring Security ====== ===== Intro ===== Probably Google wouldn't honour this page at the top of the search engines when the user search for this stuff, however, here it goes my own solution to programmatically create a user using Spring Security. This solution is compatible with **any configuration** you should have in Spring Security. The only thing you should do is to inject the proper beans into this component. Let's say that you use a passwordEncoder bean which is ''org.springframework.security.authentication.encoding.ShaPasswordEncoder'': the only thing you must do is to inject the same bean into this object to getting things to work. Are you using a salt source?? No problem. Me too. Just inject your salt source into the ''saltSource'' property and that's all. Aren't you using a salt source?? No problem. Just leave blank the ''saltSource'' property and that's all you have to do. ===== The code ===== package com.supermanhamuerto.util; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.authentication.dao.SaltSource; import org.springframework.security.authentication.encoding.PasswordEncoder; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.provisioning.JdbcUserDetailsManager; import org.springframework.security.core.GrantedAuthority; public class BatchUserCreator { private static Log log = LogFactory.getLog(BatchUserCreator.class); private JdbcUserDetailsManager userDetailsManager; private SaltSource saltSource = null; private PasswordEncoder passwordEncoder = null; private UserDetails user; private String username; private String password; private boolean enabled; private boolean accountNonExpired; private boolean credentialsNonExpired; private boolean accountNonLocked; private List grantedAuthorities; public JdbcUserDetailsManager getUserDetailsManager() { return userDetailsManager; } public void setUserDetailsManager(JdbcUserDetailsManager userDetailsManager) { this.userDetailsManager = userDetailsManager; } public SaltSource getSaltSource() { return saltSource; } public void setSaltSource(SaltSource saltSource) { this.saltSource = saltSource; } public PasswordEncoder getPasswordEncoder() { return passwordEncoder; } public void setPasswordEncoder(PasswordEncoder passwordEncoder) { this.passwordEncoder = passwordEncoder; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public boolean isAccountNonExpired() { return accountNonExpired; } public void setAccountNonExpired(boolean accountNonExpired) { this.accountNonExpired = accountNonExpired; } public boolean isCredentialsNonExpired() { return credentialsNonExpired; } public void setCredentialsNonExpired(boolean credentialsNonExpired) { this.credentialsNonExpired = credentialsNonExpired; } public boolean isAccountNonLocked() { return accountNonLocked; } public void setAccountNonLocked(boolean accountNonLocked) { this.accountNonLocked = accountNonLocked; } public List getGrantedAuthorities() { return grantedAuthorities; } public void setGrantedAuthorities(List grantedAuthorities) { this.grantedAuthorities = grantedAuthorities; } public void setGrantedAuthoritiesByName(List grantedAuthorities) { ArrayList definitiveList = new ArrayList(); Iterator itAuthString = grantedAuthorities.iterator(); while( itAuthString.hasNext() ) { String roleName = itAuthString.next(); definitiveList.add( new SimpleGrantedAuthority( roleName ) ); } // while this.grantedAuthorities = definitiveList; } public void createUser() { if( log.isWarnEnabled() ) { log.warn( "Creating user with name " + username ); log.warn( "Authorities: " ); Iterator itAuth = grantedAuthorities.iterator(); while( itAuth.hasNext() ) { GrantedAuthority auth = itAuth.next(); log.warn( auth.getAuthority() ); } // while } // log.isWarnEnabled() Object salt = null; user = new User( username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, grantedAuthorities ); if( this.saltSource != null ) { salt = this.saltSource.getSalt( user ); } // calculate what hashedPassword would be in this configuration String hashedPassword = passwordEncoder.encodePassword( user.getPassword(), salt ); // create a new user with the hashed password UserDetails userHashedPassword = new User( username, hashedPassword, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, grantedAuthorities ); // if the user extists, delete it if( userDetailsManager.userExists( userHashedPassword.getUsername() ) ) { userDetailsManager.deleteUser( userHashedPassword.getUsername() ); } // and finally, create the user userDetailsManager.createUser( userHashedPassword ); } } ===== An example of the applicationContext.xml ===== ROLE_GUEST ROLE_USER ROLE_BOARD ROLE_ADMIN ROLE_MEMBER ===== The resources ===== Of course, I've read the Spring Security source code to locate the exact point where the password is encoded and compared with the stored password. Is this point: http://www.jarvana.com/jarvana/view/org/springframework/security/spring-security-core/3.0.2.RELEASE/spring-security-core-3.0.2.RELEASE-sources.jar!/org/springframework/security/authentication/encoding/MessageDigestPasswordEncoder.java?format=ok Locate the function ''isPasswordValid''. Has this code: public boolean isPasswordValid(String encPass, String rawPass, Object salt) { String pass1 = "" + encPass; String pass2 = encodePassword(rawPass, salt); return pass1.equals(pass2); } So, ''encodePassword'' is the function we need to call. But hold on!!! How is this ''Object salt'' yielded??? If you look here: http://www.jarvana.com/jarvana/view/org/springframework/security/spring-security-core/3.0.2.RELEASE/spring-security-core-3.0.2.RELEASE-sources.jar!/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java?format=ok you will see this code: Object salt = null; if (this.saltSource != null) { salt = this.saltSource.getSalt(userDetails); } Which is exactly what we neeed. ~~DISQUS~~