2
votes

I use Spring MVC in my application and the login is authenticated by spring security. I have the following two methods in my UserServiceImpl.java class, public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException {

        ApplicationTO applicationTO = null;
        try
            {
                applicationTO = applicationService.getApplicationTO(adminDomainName);
            }
        catch (ApplicationPropertyException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        UserTO userTO = getUserTO(applicationTO.getApplicationId(), userName);
        if (userTO == null)
            {
                throw new UsernameNotFoundException("user not found");
            }
        httpSession.setAttribute("userTO", userTO);
        return buildUserFromUserEntity(userTO);
    }


User buildUserFromUserEntity(UserTO userTO)
            {
                String username = userTO.getUsername();
                String password = userTO.getPassword();
                int userId = userTO.getUserId();
                int applicationId = userTO.getApplicationId();
                boolean enabled = userTO.isEnabled();
                boolean accountNonExpired = true;
                boolean credentialsNonExpired = true;
                boolean accountNonLocked = true;
                User user = new User(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, getAuthority(applicationId, userId));
                return user;
            }

I am relatively new to Spring and do not have much idea about the spring security part. In my spring-security.xml file, I have the following,

<form-login login-page="/login" default-target-url="/module/user-home/welcome"
    authentication-failure-url="/login?error" username-parameter="username"
    password-parameter="password" />
<logout logout-success-url="/login?logout" />

<beans:bean id="daoAuthenticationProvider"
 class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
  <beans:property name="userDetailsService" ref="userDetailsService"/>
</beans:bean>

<beans:bean id="authenticationManager"
    class="org.springframework.security.authentication.ProviderManager">
  <beans:property name="providers">
    <beans:list>
      <beans:ref local="daoAuthenticationProvider" />
    </beans:list>
  </beans:property>
</beans:bean>

And my login form has the action set as follows:

<form id="loginForm" class="form-horizontal" role="form" name='loginForm' action="${rc.getContextPath()}/j_spring_security_check" method='POST'>

Now I am trying to get the value of the password that the user has entered in the login form, either inside the loadUserByUsername method or by adding a new method to the UserServiceImpl.java class.

I use the following to encrypt my passwords before saving them. What API and algorithm to be used to encrypt and decrypt a password using java

So during login, spring security compares the user entered password with encrypted password from the database and the login fails. But as per the implementation suggested in the above link, there is a method to compare the password and the encrypted password to check if they are same. That is possible only if I get access to the user entered password. This is the reason I am trying to get the user entered password.

2
No and nor should you as that is done by Spring Security for you.M. Deinum
As already mentioned Spring Security will validate the password for you. Why do you need access to the password?Rob Winch
@RobWinch, I have specified the reason why I need access to password, please suggest if you got some idea on how I can handle the issueGeo Thomas

2 Answers

9
votes

if you want, you can create your own AuthenticationProvider

public class CustomAuthenticationProvider implements AuthenticationProvider{

    private UserDetailsService service;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication;
        String username = token.getName();
        String password = token.getCredentials(); // retrieve the password 
        // do something here

        // if ok then return the authentication
        return new UsernamePasswordAuthenticationToken(username, password, authorities);
    }
}

and plug it to your security configuration

<beans:bean id="customAuthenticationProvider"
 class="com.xxx.CustomAuthenticationProvider">
  <beans:property name="userDetailsService" ref="userDetailsService"/>
</beans:bean>

<beans:bean id="authenticationManager"
    class="org.springframework.security.authentication.ProviderManager">
  <beans:property name="providers">
    <beans:list>
      <beans:ref local="customAuthenticationProvider" />
    </beans:list>
  </beans:property>
</beans:bean>
4
votes

As was suggested in answer by MangEngkus you can implement your own custom AuthenticationProvider but based on your description I don't think you need to do that.

You don't need to implement your own password hashing mechanism into spring-security. You just need to define BCryptPasswordEncoder from spring itself.

Either this way to use the default one:

<authentication-manager>
  <authentication-provider>
    <password-encoder hash="bcrypt" />
  </authentication-provider>
</authentication-manager>

Or create your own bean and supply it to default provider:

<authentication-manager>
  <authentication-provider>
    <password-encoder ref="encoder" />
  </authentication-provider>
</authentication-manager>

<beans:bean id="encoder" 
  class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
    <beans:constructor-arg name="strength" value="15" />
</beans:bean>

But for you, this is the way: :)

<beans:bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
  <beans:property name="userDetailsService" ref="userDetailsService"/>
  <beans:property name="passwordEncoder" ref="encoder" />
</beans:bean>

<bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>