所以我在Spring Boot中使用Spring Security。我想创建自己的AuthenticationProvider
,这是以我自己的方式使用数据库,所以我使用这个authenticate
方法做到了:
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String email = authentication.getName();
String password = authentication.getCredentials().toString();
UserWithEmail userWithEmail = authService.getUserByEmail(email);
if (userWithEmail == null)
return null;
if (userWithEmail.getPassword().equals(password)) {
UsernamePasswordAuthenticationToken authenticated_user = new UsernamePasswordAuthenticationToken(userWithEmail, password, Arrays.asList(REGISTERED_USER_SIMPLE_GRANTED_AUTHORITY));
return authenticated_user;
} else {
return null;
}
}
如果我使用带有表单的默认/登录页面,那么效果很好,之后如果我将以下ModelAttribute
添加到Controller
,它就会被{{1}正确填充对象:
UserWithEmail
问题是,如果我点击/登录?注销,它会正确显示我已注销,但如果我再次通过控制器,我仍然会获得与主体相同的@ModelAttribute("userwithemail")
public UserWithEmail userWithEmail(){
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
Object principal = authentication.getPrincipal();
if (principal instanceof UserWithEmail)
return (UserWithEmail) principal;
else
return null;
}
对象,并且它具有该属性UserWithEmail
这是我的弹簧安全Java配置:
authenticated=true
我是Spring Security的新手,所以也许我错过了什么......有人可以帮忙吗?
答案 0 :(得分:1)
根据文档here for CSRF POST是强制注销的,以及用于攻击保护的CSRF令牌。
因为我使用的是自定义模板引擎,所以我必须在请求的模型属性中拦截CSRF令牌,如下所示:
@ModelAttribute("crsf_token")
public CsrfToken getcrsfToken(HttpServletRequest request, Model model) {
CsrfToken token = (CsrfToken) request.getAttribute("_csrf");
return token;
}
因为它没有被复制到我的模板引擎的模型中。