java:springsecurityprogrammaticallycreateuser
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| java:springsecurityprogrammaticallycreateuser [2012/07/17 19:02] – creado rlunaro | java:springsecurityprogrammaticallycreateuser [2022/12/02 21:02] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Create a user programmatically in Spring Security ====== | ||
| + | |||
| + | ===== Intro ===== | ||
| + | |||
| + | Probably Google wouldn' | ||
| + | |||
| + | 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 '' | ||
| + | |||
| + | Are you using a salt source?? No problem. Me too. Just inject your salt source into the '' | ||
| + | |||
| + | Aren't you using a salt source?? No problem. Just leave blank the '' | ||
| + | |||
| + | ===== The code ===== | ||
| + | |||
| + | |||
| + | <code java> | ||
| + | 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< | ||
| + | |||
| + | 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< | ||
| + | { | ||
| + | return grantedAuthorities; | ||
| + | } | ||
| + | |||
| + | public void setGrantedAuthorities(List< | ||
| + | { | ||
| + | this.grantedAuthorities = grantedAuthorities; | ||
| + | } | ||
| + | |||
| + | public void setGrantedAuthoritiesByName(List< | ||
| + | { | ||
| + | ArrayList< | ||
| + | |||
| + | 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( " | ||
| + | log.warn( " | ||
| + | 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(), | ||
| + | |||
| + | // 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 ===== | ||
| + | |||
| + | |||
| + | <code xml> | ||
| + | < | ||
| + | |||
| + | Create user administrator............................................. | ||
| + | |||
| + | WARNING!!!! USE IT ONLY THE FIRST TIME TO SET UP THE FIRST USER!!!!! | ||
| + | |||
| + | Uncomment this bean only to create programmatically the administrator | ||
| + | (or other users) and only for fresh installations | ||
| + | |||
| + | --> | ||
| + | <bean id=" | ||
| + | class=" | ||
| + | init-method=" | ||
| + | scope=" | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | </ | ||
| + | |||
| + | ===== 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:// | ||
| + | |||
| + | Locate the function '' | ||
| + | |||
| + | <code java> | ||
| + | public boolean isPasswordValid(String encPass, String rawPass, Object salt) { | ||
| + | String pass1 = "" | ||
| + | String pass2 = encodePassword(rawPass, | ||
| + | |||
| + | return pass1.equals(pass2); | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | |||
| + | So, '' | ||
| + | |||
| + | http:// | ||
| + | |||
| + | you will see this code: | ||
| + | |||
| + | <code java> | ||
| + | Object salt = null; | ||
| + | |||
| + | if (this.saltSource != null) { | ||
| + | salt = this.saltSource.getSalt(userDetails); | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | |||
| + | Which is exactly what we neeed. | ||
| + | |||
| + | |||
| + | ~~DISQUS~~ | ||
| + | |||
| + | |||
