春天3,Spring Security.提取经过身份验证的用户对象

jac*_*ekn 4 spring-security

这是一个Spring Security问题.

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

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

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

下面是一个简单的控制器来说明我的挑战.它的用户域对象是硬编码的.我需要用将从Spring Security会话获取User对象的代码替换该块.我正在寻找在Spring 3中实现这一目标的最佳方法.

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

    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;
        }
    
    Run Code Online (Sandbox Code Playgroud)

===更新2012-01-07 ========================================= =============

我正在和卢克的建议一起工作.从会话中获取UserDetails并将其转换为返回的我的域User对象的方法在我的UserService中.

这是我的控制器:

@Controller
public class HomeController {
@Autowired
private UserService userService;

@RequestMapping(value="/home.html", method=RequestMethod.GET)
public ModelAndView getHomePage(Map<String, Object> model) {

    // Construct HomePage bean  
    HomeBean bean=new HomeBean();
    User currentUser=userService.getCurrentlyAuthenticatedUser();
    bean.setCurrentUserName(currentUser.getUserName());
Run Code Online (Sandbox Code Playgroud)

这是UserServiceImpl.getCurrentlyAuthenticatedUser()的关键代码:

@Override
public User getCurrentlyAuthenticatedUser() {
    User currentUser=new User();

    Authentication a = SecurityContextHolder.getContext().getAuthentication();
    UserDetails currentUserDetails = (UserDetails) a.getPrincipal();
    if(currentUserDetails==null) {
        return currentUser;
    }

    currentUser.setUserName(currentUserDetails.getUsername());
Run Code Online (Sandbox Code Playgroud)

这有效,但我这样做对吗?反馈非常感谢.我仍然无法从会话中检索我的用户域对象.我正在检索Spring的UserDetails对象,并使用它构建我的域User对象,但在此过程中会丢失一些信息.

Sha*_*eep 8

通常,成功中包含的主要对象Authentication将是您的用户对象的实例.因此,要快速解决方案,请使用

Authentication a = SecurityContextHolder.getContext().getAuthentication();
User currentUser = (User)a.getPrincipal();
Run Code Online (Sandbox Code Playgroud)

但是(一旦你开始工作),你可能想看看我刚才给出的关于如何注入自定义安全上下文访问器的答案(针对类似问题).