将用户对象存储在与Spring Security的会话中

时间:2017-03-16 14:00:41

标签: java spring spring-mvc spring-boot spring-security

根据我的理解,有许多不同的方法可以在Spring Security中检索经过身份验证的用户名。

我目前通过将Principal作为控制器方法参数包含来获取用户名:

@RequestMapping(value = "/dashboard", method = RequestMethod.GET)
public ModelAndView displayHomePage(ModelAndView modelAndView, Principal principal) {

  modelAndView.addObject("email", principal.getName());

  // Render template located at src/main/resources/templates/dashboard.html
  modelAndView.setViewName("dashboard");

  return modelAndView;
}

Spring Security是否为我提供了一种简单的方法将User对象存储到会话中,以便通过任何控制器方法轻松检索它?

我希望每次都避免执行数据库查找:

// Lookup user in database by e-mail
User user = userService.findUserByEmail(principal.getName());

我使用的是Spring Security 4.2。

2 个答案:

答案 0 :(得分:5)

Spring Security为您提供了一种可以快速轻松访问的静态方法:

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String name = auth.getName();

或者

User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String name = user.getUsername();

也许你想在基础抽象类中做到这一点

public abstract class BaseController {
    protected User getCurrentUser() {
        return (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    }
}
...
public YourController extends BaseController {
...
}

<强>更新

如果要将当前经过身份验证的用户存储在会话中,则需要按照@gkatzioura的建议首次在对象中存储。

@Component
@Scope("session")
public class MySessionInfo {

    private User user;

    protected User getCurrentUser() {
        if (user == null) {
            user = userService.findUserByEmail(SecurityContextHolder.getContext().getAuthentication().getPrincipal().getName());
        }
        return user;
    }
}

您可以在您的控制器中注入此bean,例如

@Autowired
private MySessionInfo mySessionInfo;

您必须注意用户未登录时的情况,但这是另一个问题。

答案 1 :(得分:0)

您始终可以使用Spring安全性提供的方法来获取Authentication.class提供的名称,权限和所有内容等基本信息。

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
authentication.getAuthorities();
authentication.getName();

但是如果你想了解更多信息,使用会话bean来存储信息也是一个好主意。

@Component
@Scope("session")
public class UserInfo { .. }