我使用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);
}
这是一种正确的操作方式还是有更好的解决方案?
由于
答案 0 :(得分:2)
如果正确配置了身份验证和授权,则Authentication
对象不应为null
。这种情况应该由servlet过滤器(或者用于将Spring Security与Web应用程序环境集成的方法)捕获。
如果配置正确,有两种可能的情况:
Authentication
对象。WebSecurityConfigurerAdapter
派生的对象来配置详细信息。假设您允许匿名访问,但某些操作需要身份验证,处理此操作的正确方法(如果您无法在控制器级别检测到它)是让您的模型抛出AccessDeniedException
。然后,ExceptionTranslationFilter
可以处理此异常,可以处理重定向到登录页面。
有关如何正确设置在Web应用程序中使用Spring Security时所需的过滤器的详细说明,请参阅Spring Security Reference。
在任何情况下,您都不应尝试从DAO访问HttpServletRequest
或HttpServletResponse
。它违反了一般合同,模型代码不应该依赖于控制器,并使整个代码更难理解。例如,您的DAO稍后可能会被不同的代码(例如,Web服务API,应用程序服务器等)使用,这些代码以非常不同的方式处理身份验证和授权,甚至没有HTTP请求上下文。在这种情况下,您的DAO将无法再正常工作。当仅使用Authentication
对象并抛出AccessDeniedException
时,您的DAO仍然是可移植的,并且可以在任何环境中使用。