Reputation: 21
SecurityContextHolder in my app is always returning null Authentication on action in my web-page I'm trying to get authenticated user to get his name from DB and to store new record with appropriate user. Here is simple code:
@Controller
public class SomeController {
@Autowired
EngineerService engineerService;
@Autowired
OtherService otherService;
@MessageMapping("/saveSomething")
public String saveSomething(String input){
String userName = SecurityContextHolder.getContext().getAuthentication().getName();
Engineer engineer = engineerService.getByLogin(userName);
otherService.SaveNewEntity(input, engineer);
return "trigger";
}
}
But first string in this code always cause nullPointerException, cause getAuthentication() return null. here is my SecurityController:
@Controller
public class SecurityController {
@RequestMapping(value="/", method= RequestMethod.GET)
public String login(){
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication.isAuthenticated()){
return "redirect:/main.html";
}else{
return "redirect:/error";
}
}
@RequestMapping(value="/user", method = RequestMethod.GET)
@ResponseBody
public User getUser() {
User user = new User();
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null) {
String name = auth.getName();
user.setName(name);
}
return user;
}
}
I've tried to use getUser() method, but it always return string "user", even if I login with user "admin". Here is SecurityConfig:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("admin").password("pass").roles("ADMIN");
auth.inMemoryAuthentication().withUser("user").password("pass").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/css/signin.css").permitAll()
.antMatchers("/webjars/bootstrap/css/bootstrap.min.css").permitAll()
.anyRequest().authenticated()
.and().formLogin().loginPage("/login.html").permitAll();
}
}
Unfortunately, this code not mine and I've spent whole day playing around SecurityContextHolder. I've understood that needed userName located in another thread, but I can't understand, how to get right Context to get right Authentication object.
Upvotes: 1
Views: 2937
Reputation: 21
So, the only thing needed was to add Principal with annotation to method.
@Controller
public class SomeController {
@Autowired
EngineerService engineerService;
@Autowired
OtherService otherService;
@MessageMapping("/saveSomething")
public String saveSomething(@AuthenticationPrincipal Principal user, String input){
String userName = user.getName();
Engineer engineer = engineerService.getByLogin(userName);
otherService.SaveNewEntity(input, engineer);
return "trigger";
}
}
Upvotes: 1