User Tools

Site Tools


java:springsecurityprogrammaticallycreateuser

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
java:springsecurityprogrammaticallycreateuser [2012/07/17 21:02] – creado rlunarojava:springsecurityprogrammaticallycreateuser [2022/12/02 22:02] (current) – external edit 127.0.0.1
Line 1: Line 1:
 +====== 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 =====
 +
 +
 +<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<GrantedAuthority> 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<GrantedAuthority> getGrantedAuthorities()
 +    {
 +    return grantedAuthorities;
 +    }
 +
 + public void setGrantedAuthorities(List<GrantedAuthority> grantedAuthorities)
 +    {
 +    this.grantedAuthorities = grantedAuthorities;
 +    }
 +
 + public void setGrantedAuthoritiesByName(List<String> grantedAuthorities)
 + {
 + ArrayList<GrantedAuthority> definitiveList = new ArrayList<GrantedAuthority>();
 +
 + Iterator<String> 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<GrantedAuthority> 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 );
 +
 + }
 +
 +
 +}
 +
 +</code>
 +
 +===== 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="batchUserCreator"
 + class="com.supermanhamuerto.util.BatchUserCreator"
 + init-method="createUser"
 + scope="singleton">
 + <property name="userDetailsManager" ref="jdbcUserDetailsManager"/>
 + <property name="saltSource" ref="saltSource"/>
 + <property name="passwordEncoder" ref="passwordEncoder"/>
 + <property name="username" value="MY-USERNAME-GOES-HERE"/>
 + <property name="password" value="MY-SECRET-PASSWORD-GOES-HERE"/>
 + <property name="enabled" value="true"/>
 + <property name="accountNonExpired" value="true"/>
 + <property name="accountNonLocked" value="true"/>
 + <property name="grantedAuthoritiesByName">
 + <list>
 + <value>ROLE_GUEST</value>
 + <value>ROLE_USER</value>
 + <value>ROLE_BOARD</value>
 + <value>ROLE_ADMIN</value>
 + <value>ROLE_MEMBER</value>
 + </list>
 + </property>
 + </bean>
 +
 +
 +
 +</code>
 +
 +===== 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: 
 +
 +<code java>
 +public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
 +        String pass1 = "" + encPass;
 +        String pass2 = encodePassword(rawPass, salt);
 +
 +        return pass1.equals(pass2);
 +    }
 +
 +</code>
 +
 +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:
 +
 +<code java>
 +        Object salt = null;
 +
 +        if (this.saltSource != null) {
 +            salt = this.saltSource.getSalt(userDetails);
 +        }
 +
 +</code>
 +
 +Which is exactly what we neeed.
 +
 +
 +~~DISQUS~~
 +
 +