【发布时间】:2017-11-21 16:07:39
【问题描述】:
我的应用程序中的SecurityContextHolder 总是在我的网页中返回空身份验证 我正在尝试让经过身份验证的用户从数据库中获取他的名字并与适当的用户一起存储新记录。这是简单的代码:
@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";
}
}
但是这段代码中的第一个字符串总是会导致 nullPointerException,导致 getAuthentication() 返回 null。这是我的安全控制器:
@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;
}
}
我尝试使用 getUser() 方法,但它总是返回字符串“user”,即使我使用用户“admin”登录也是如此。 这是安全配置:
@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();
}
}
不幸的是,这段代码不是我的,我花了一整天的时间在 SecurityContextHolder 上玩。我已经了解需要位于另一个线程中的用户名,但我不明白,如何获取正确的 Context 以获取正确的 Authentication 对象。
【问题讨论】:
-
对于初学者,您是否有理由不只是使用
@AuthenticationPrincipal? -
只需将
Principal添加为方法参数,该参数将为您填充当前用户。无需像那样将您的代码绑定到 Spring Security。 -
我对春天很陌生。谢谢,太明显了!
标签: java spring authentication