Ilkar
Ilkar

Reputation: 2177

SpringSecurity UserDetailsService get password

I'm creating authentication service in Spring.

I'm using UserDetailsService to get form variables, but i found that loadUserByUsername has only one variable - userName.

How to get password ?

public class userAuthentication implements UserDetailsService{

    private @Autowired
    ASPWebServicesUtils aspWebServicesUtils;

    @Override
    public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {

        //how to get password ?

        User user = new User("test", "test", true, true, true, true, getAuthorities(true));

        return user;  

    }

    private List<GrantedAuthority> getAuthorities(boolean isAdmin){

        List<GrantedAuthority> authorityList = new ArrayList<GrantedAuthority>(2);
        authorityList.add(new SimpleGrantedAuthority("USER_ROLE"));
        if(isAdmin){
            authorityList.add(new SimpleGrantedAuthority("ADMIN_ROLE"));
        }
        return authorityList;

    }
//...
}

Thanks

Upvotes: 15

Views: 26842

Answers (6)

xxg
xxg

Reputation: 2148

Get password in UserDetailsService implementation by request.getParameter("password"):

public class MyUserDetailsService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String password = request.getParameter("password"); // get from request parameter
        ......
    }
}

RequestContextHolder is base on ThreadLocal.

If your project is base on Spring Framework (not Spring Boot), add RequestContextListener to web.xml

<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

Upvotes: 3

Siva Anand
Siva Anand

Reputation: 2882

XML Implementation:

<authentication-manager  alias="loginAuthenticationManager">
    <authentication-provider ref="loginAuthenticationProvider" />
</authentication-manager>

<!-- Bean implementing AuthenticationProvider of Spring Security -->
<beans:bean id="loginAuthenticationProvider" class="com.config.LoginAuthenticationProvider">
</beans:bean>

AuthenticationProvider:

public class LoginAuthenticationProvider implements AuthenticationProvider {
    @Override
    public Authentication authenticate(Authentication authentication)
            throws AuthenticationException {
        String name = authentication.getName();
        // You can get the password here
        String password = authentication.getCredentials().toString();

        // Your custom authentication logic here
        if (name.equals("admin") && password.equals("pwd")) {
            List<GrantedAuthority> grantedAuths = new ArrayList<>();
            grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
            return new UsernamePasswordAuthenticationToken(name, password, grantedAuths);
        }
        return null;
    }
    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}

Upvotes: 1

Robin Rizvi
Robin Rizvi

Reputation: 5183

Some of the standard (out-of-the-box) mechanisms to retrieve the user information and provide authentication information are:

  • inMemoryAuthentication
  • jdbcAuthentication
  • ldapAuthentication
  • userDetailsService

If the above does not suit your purpose and you need to have a custom solution, you can create and configure a new authentication provider like so:

Security Configuration:

@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    @Autowired
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(new CustomAuthenticationProvider());
    }

    ....
}

Authentication Provider:

public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication)
            throws AuthenticationException {
        String name = authentication.getName();
        // You can get the password here
        String password = authentication.getCredentials().toString();

        // Your custom authentication logic here
        if (name.equals("admin") && password.equals("pwd")) {
            Authentication auth = new UsernamePasswordAuthenticationToken(name,
                    password);

            return auth;
        }

        return null;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }

}

Upvotes: 17

Arun P Johny
Arun P Johny

Reputation: 388316

If you look at the User object, the second parameter in the constructor is the password.

The UserDetailsService is used to load the user from a back-end structure like database. The loadUserByUsername method is called when a user tries to login with a username and password, then it is the responsibility of the service to load the user definition and return it to the security framework. The required details includes data like username, password, accountNonExpired, credentialsNonExpired, accountNonLocked and authorities.

Once the spring security receives the user object, it will validate the user against the password entered by the user and other data like user account status (accountNonExpired, credentialsNonExpired etc)

Upvotes: 20

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279930

I believe a UserDetailsService is supposed to be used to acquire a UserDetails object from some back end storage, database, flat file, etc. Once you have that UserDetails, spring security (or you) have to compare it to the username (or other principals) and password (the credentials) provided by the user in order to authenticate that user.

I don't think you are using it the way it is intended.

Upvotes: 3

NimChimpsky
NimChimpsky

Reputation: 47280

the loadUserByUsername(String name) is a method defined on an interface (userServicedetails I think), which your service implements. You have to write the implementation.

Just as you have to write the implementation for getPassword() or similar ... spring does not provide that. I imagine the password is stored in your user object, but you wrote that ... did you create a getPassword() method ?

Upvotes: 0

Related Questions