I have created a simple spring web mvc app and I have one problem. After authentication I try to get an authentication object and for some reason it's credentials is null.
In this project I have a custom AuthenticationProvider which looks like this:
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
@PostConstruct
public void init() {
roleService.AddStandardRolesIfNeeded();
userService.AddUserWithAdminRoleIfNotExists("a");
}
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
Object credentials = authentication.getCredentials();
if(!(credentials instanceof String)) {
return null;
}
String username = authentication.getName();
String password = credentials.toString(); //password isn't null here
User user = userService.findByUsernameAndPassword(username, password);
if(user == null) {
throw new BadCredentialsException("Authentication failed for " + username);
}
List<GrantedAuthority> authorities = new ArrayList<>();
for(Role role : user.getRoles()) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
Authentication auth = new
UsernamePasswordAuthenticationToken(username, password, authorities);
return auth;
}
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
I am interested in if it is intentionally done in spring security or I am missing something.
I solved this by passing user object to UsernamePasswordAuthenticationToken
constructor instead of username in place of principal.
I changed this:
Authentication auth = new
UsernamePasswordAuthenticationToken(username, password, authorities);
to this:
Authentication auth = new
UsernamePasswordAuthenticationToken(user, password, authorities);
And in controller I get the user so:
User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();