Spring security 春季3,春季安全。提取经过身份验证的用户对象

Spring security 春季3,春季安全。提取经过身份验证的用户对象,spring-security,Spring Security,这是一个春季安全问题 在我的应用程序中,我有一个用户实体作为域对象。此对象包含支持Spring UserDetails对象的实现。身份验证(登录/注销)过程工作正常 挑战在于,我需要从会话中提取该对象,以便在代码中做出“业务逻辑”决策 我一直在阅读有关查询SecurityContextHolder的文章,但坦率地说,我仍然不知道什么是最好的方法,因为多个Spring版本似乎是这些讨论中的一个因素。而且,主体对象不是我的解决方案,因为它似乎不包含任何访问级别或角色信息 下面是一个简单的控制器来说明

这是一个春季安全问题

在我的应用程序中,我有一个用户实体作为域对象。此对象包含支持Spring UserDetails对象的实现。身份验证(登录/注销)过程工作正常

挑战在于,我需要从会话中提取该对象,以便在代码中做出“业务逻辑”决策

我一直在阅读有关查询SecurityContextHolder的文章,但坦率地说,我仍然不知道什么是最好的方法,因为多个Spring版本似乎是这些讨论中的一个因素。而且,主体对象不是我的解决方案,因为它似乎不包含任何访问级别或角色信息

下面是一个简单的控制器来说明我的挑战。它有我的用户域对象硬编码。我需要用从Spring安全会话获取用户对象的代码替换该块。我正在寻找在Spring3中实现这一点的最佳方法

  • 我可以将此对象作为域对象获取,还是需要将其作为Spring UserDetails对象获取并手动转换
  • 这个安全上下文查找可以以某种方式注入到我的控制器中吗

    public class HomeController {
        @RequestMapping(value="/home.html", method=RequestMethod.GET)
        public ModelAndView getHomePage(Map<String, Object> model) {
    
            // Get current user
            User currentUser=new User();
            currentUser.setUserName("Admin");
            currentUser.setAccessLevel(UserAccessLevel.ADMINISTRATOR);
    
            // Construct HomePage bean  
            HomeBean bean=new HomeBean();
            bean.setCurrentUserName(currentUser.getUserName());
    
            // Construct list of catalogs
            Collection<String> catalogList=new ArrayList<String>();
            catalogList.add("articles");
            catalogList.add("files");
            catalogList.add("comments");
            if(currentUser.hasAdministratorAccessLevel()) {
                catalogList.add("users");
            }
            bean.setCatalogList(catalogList);
    
            // Construct and return ModelAndView
            ModelAndView mav=new ModelAndView();
            mav.setViewName(WebView.HOME_PAGE.getViewName());
            mav.addObject(bean.getBeanId(), bean);
    
            return mav;
        }
    

    这行得通,但我做得对吗?非常感谢您的反馈。我仍然无法从会话中检索我的用户域对象。我正在检索Spring的UserDetails对象,并用它构造我的域用户对象,但在此过程中一些信息丢失。

    通常,成功的
    身份验证中包含的主体对象将是您的用户对象的实例。因此,要快速解决问题,请使用

    Authentication a = SecurityContextHolder.getContext().getAuthentication();
    User currentUser = (User)a.getPrincipal();
    

    但是(一旦你成功了),你可能想看看我刚才给出的关于如何解决的答案。

    Spring还提供了@AuthenticationPrincipal注释,用于解析Authentication.getPrincipal()。它可以像下面这样使用

    public  ResponseEntity<UserProfileResponse>UserProfile(@AuthenticationPrincipal JwtAuthenticationToken principal){
    
    public ResponseEntityUserProfile(@AuthenticationPrincipal JwtAuthenticationToken principal){
    
    java.lang.ClassCastException:org.springframework.security.core.userdetails.User不能强制转换为com.modelsite.domain.users如果我不能以我的域用户的身份检索用户对象,那就有点麻烦了。从userdetails,我可以知道我在处理什么访问级别,但我需要的另一条信息是userId.userName和userId对我来说是两件不同的事情。如果我无法从会话中检索到它,这意味着我需要从数据库中获取用户。这是我想要避免的。你应该使用
    UserDetails服务
    配置Spring Security,它返回你的用户对象的一个实例(自定义
    UserDetails
    实例)当用户进行身份验证时。通过这种方式,它将直接从
    SecurityContextHolder
    获得,而无需创建任何新的中间对象。有关使用
    UserDetailsService
    的详细信息。
    Authentication a = SecurityContextHolder.getContext().getAuthentication();
    User currentUser = (User)a.getPrincipal();
    
    public  ResponseEntity<UserProfileResponse>UserProfile(@AuthenticationPrincipal JwtAuthenticationToken principal){