Spring安全性 - Authentication为null时要执行的操作

时间:2016-05-22 14:30:17

标签: spring spring-security

我使用Spring Security在我的网络应用中管理身份验证。 有了它,我根据用户的名称管理对某些对象的访问。

所以,在我的DAO级别中,我有这个方法,它为我提供了用户的Park对象列表

public List<Park> findParkByUser(int offset) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();

        List<Park> parks = new ArrayList<Park>();
        try {
        if(auth != null){
            String name = auth.getName();
            User user = userService.findBySso(name);

        int userId = user.getId();
        Criteria criteria = createEntityCriteria();

            criteria.createAlias("users", "u");
            if(offset >= 0){
            criteria.add(Restrictions.eq("u.id", userId)).setFirstResult(offset).setMaxResults(elementsPerPage);
            }
            criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
            parks = (List<Park>) criteria.list();

        } else {

            logger.debug("Auth error");

        }
        } catch (NullPointerException e) {
            logger.error("Auth error",e);

        }
        return parks;
    }

现在的问题是,当会话超时或cookie过期时,我会获得null身份验证。我想将用户重定向到登录页面,但我是在DAO级别,而不是在Controller中。我以为我可以从控制器HttpServeletRequest和Response获得并使用自定义注销管理器

public void logout(HttpServletRequest request, HttpServletResponse response) {
        CookieClearingLogoutHandler cookieClearingLogoutHandler = new CookieClearingLogoutHandler(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
        SecurityContextLogoutHandler securityContextLogoutHandler = new SecurityContextLogoutHandler();
        cookieClearingLogoutHandler.logout(request, response, null);
        securityContextLogoutHandler.logout(request, response, null);
    }

这是一种正确的操作方式还是有更好的解决方案?

由于

1 个答案:

答案 0 :(得分:2)

如果正确配置了身份验证和授权,则Authentication对象不应为null。这种情况应该由servlet过滤器(或者用于将Spring Security与Web应用程序环境集成的方法)捕获。

如果配置正确,有两种可能的情况:

  1. 您的应用程序允许匿名访问。在这种情况下,相应的过滤器将设置表示此匿名身份验证的Authentication对象。
  2. 您的应用程序不允许匿名访问。在这种情况下,过滤器应该已经捕获了丢失的身份验证并将用户重定向到登录页面。使用Java配置时,可以通过在应用程序上下文中提供从WebSecurityConfigurerAdapter派生的对象来配置详细信息。
  3. 假设您允许匿名访问,但某些操作需要身份验证,处理此操作的正确方法(如果您无法在控制器级别检测到它)是让您的模型抛出AccessDeniedException。然后,ExceptionTranslationFilter可以处理此异常,可以处理重定向到登录页面。

    有关如何正确设置在Web应用程序中使用Spring Security时所需的过滤器的详细说明,请参阅Spring Security Reference

    在任何情况下,您都不应尝试从DAO访问HttpServletRequestHttpServletResponse。它违反了一般合同,模型代码不应该依赖于控制器,并使整个代码更难理解。例如,您的DAO稍后可能会被不同的代码(例如,Web服务API,应用程序服务器等)使用,这些代码以非常不同的方式处理身份验证和授权,甚至没有HTTP请求上下文。在这种情况下,您的DAO将无法再正常工作。当仅使用Authentication对象并抛出AccessDeniedException时,您的DAO仍然是可移植的,并且可以在任何环境中使用。