I setup my Spring Security application according to the reference document and after hours of troubleshooting I continue to get a null @AuthenticationPrincipal passed into my controller.
The authentication mechanism is working fine against the users in my database but still a null @AuthenticationPrincipal. I consulted several internet posts but still I am getting null.
WebSecurityConfig:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserService userService;
@Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
public DaoAuthenticationProvider provider(){
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(passwordEncoder());
provider.setUserDetailsService(userService);
return provider;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/registration").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(provider());
}
}
Message (entity):
@Entity
@Table(name = "sweater_message")
public class Message {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String text;
private String tag;
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "user_id")
private User author;
public Message(String text, String tag, User user) {
this.author = user;
this.text = text;
this.tag = tag;
}
public Message() {
}
...getters and setters
User(entity):
@Entity
@Table(name = "sweater_user")
public class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private boolean active;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(
name = "sweater_user_role",
joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id")
)
private Collection<Role> roles;
public User(String username, String password, boolean active, Collection<Role> roles) {
this.username = username;
this.password = password;
this.active = active;
this.roles = roles;
}
public User() {
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return isActive();
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return getRoles().stream().map(role -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toList());
...getters and setters
}
UserService
@Service
public class UserService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
public User save(User user) {
User saveUser = new User(
user.getUsername(),
new BCryptPasswordEncoder().encode(user.getPassword()),
true,
Arrays.asList(new Role("USER")));
return userRepository.save(saveUser);
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User findUser = userRepository.findByUsername(username);
if (findUser == null) {
throw new UsernameNotFoundException("There is no user with this username");
}
return new org.springframework.security.core.userdetails.User(
findUser.getUsername(),
findUser.getPassword(),
mapRolesToAuthorities(findUser.getRoles()));
}
public Collection<? extends GrantedAuthority> mapRolesToAuthorities(Collection<Role> roles) {
return roles.stream().map(role -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toSet());
}
}
Controller:
@PostMapping("/main")
public String add(
@AuthenticationPrincipal User user,
@RequestParam String text,
@RequestParam String tag,
Map<String, Object> model
){
...user is null
}
CodePudding user response:
try Changing @AuthenticationPrincipal User user to @AuthenticationPrincipal UserDetails userDetails since loadUserByUsername returns UserDetails