Reputation: 2177
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
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
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
Reputation: 5183
Some of the standard (out-of-the-box) mechanisms to retrieve the user information and provide authentication information are:
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
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
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
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