Spring 3安全性:未调用AccessDeniedHandler

我有一个spring 3应用程序,其配置如下。 当任何用户尝试访问某个页面并且他/她未登录时,我会收到一个带有丑陋堆栈跟踪的Access is Deniedexception。 如何处理此exception并且不允许它转储堆栈跟踪。 我实现了自己的访问被拒绝处理程序但不会被调用。

根据所请求资源的类型,我想显示自定义错误消息或页面。 这是我的弹簧配置。

如何让Spring调用我的访问被拒绝处理程序。 这是我的弹簧配置

           

下面给出了处理此exception的自定义类

 public class AccessDeniedExceptionHandler implements AccessDeniedHandler { private String errorPage; @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException arg2) throws IOException, ServletException { response.sendRedirect(errorPage); } public void setErrorPage(String errorPage) { if ((errorPage != null) && !errorPage.startsWith("/")) { throw new IllegalArgumentException("errorPage must begin with '/'"); } this.errorPage = errorPage; } } 

当我运行此应用程序时,这是我得到的错误。 我只粘贴了堆栈跟踪和Spring Debug日志的一部分。

 20:39:46,173 DEBUG AffirmativeBased:53 - Voter: org.springframework.security.access.vote.RoleVoter@5b7da0d1, returned: -1 20:39:46,173 DEBUG AffirmativeBased:53 - Voter: org.springframework.security.access.vote.AuthenticatedVoter@14c92844, returned: 0 20:39:46,178 DEBUG ExceptionTranslationFilter:154 - Access is denied (user is anonymous); redirecting to authentication entry point org.springframework.security.access.AccessDeniedException: Access is denied at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:71) at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:204) 

我该如何解决这个问题? 首先,我想阻止spring抛出那个例外。 如果它仍然抛出它,我想处理它而不是举起任何旗帜。

更新:我也附加了我的web.xml的一部分。

   HibernateFilter org.springframework.orm.hibernate3.support.OpenSessionInViewFilter   HibernateFilter /* FORWARD REQUEST   springSecurityFilterChain org.springframework.web.filter.DelegatingFilterProxy   springSecurityFilterChain /*    rowz org.springframework.web.servlet.DispatcherServlet 1  

在您的配置中您需要在您的站点上输入任何 URL时始终对用户进行身份validation:

  

我认为您应该允许用户在进入登录页面未经 身份 validation

     

如果您使用以下URL: /login/start/login/error/login/failure您可以:

   

更新:

具有此配置应该使框架将所有未经身份validation的(匿名)用户重定向到登录页面,并且所有用户都通过AccessDeniedHandler进行身份validation。 AccessDeniedException是框架的核心部分之一,忽略它并不是一个好主意。 如果您只提供Spring Security配置的部分内容,则很难提供更多帮助。

请务必阅读JavaDoc for ExceptionTranslationFilter ,详细说明框架抛出的exception,默认情况下处理的原因和方式。

如果可能的话,尝试删除你添加的尽可能多的自定义部分,如AuthenticationSuccessHandler , RememberMeAuthenticationFilter和AccessDeniedHandler ,看看问题是否有问题? 尝试获得最小的集合并逐步添加新function以查看错误的来源。

您在问题中未提及的一个重要事项是此错误消息的结果是什么? 你有HTTP 500吗? 还是HTTP 403 ? 或者你被重定向到登录页面?

如果您在问题中提到,用户未经身份validation并且他/她被重定向到登录页面,那么这就是它的工作方式。 看起来您只是因为您将DEBUG级别设置为Spring Security类而得到ExceptionTranslationFilter:172记录的错误消息。 如果是这样,那也是它的工作方式,如果你不想记录错误,那么只需提高Spring Secyruty类的日志记录级别。

更新2:

filters="none"的模式必须与设置的login-pagelogin-processing-urlauthentication-failure-ur属性相匹配,以跳过显示登录页面的页面上的所有SpringSecurity检查。处理登录。

          

当用户登录并且没有资源权限时( 此处为source ),将调用AccessDeniedHandler 。 如果要在用户未登录时处理登录页面请求,只需在security-context中配置:

  

并定义customAuthenticationEntryPoint:

   

提示不要试图与ExceptionTranslationFilter战斗 。 我试图覆盖org.springframework.security.web.access.ExceptionTranslationFilter ,没有效果:

        

ref="customAuthenticationEntryPoint"刚刚没有被调用。

我以下面的方式添加了Spring Access被拒绝的页面:Spring Frame Work:3.1 Spring Security:3.1,Java 1.5+

输入* -security.xml:

  

例:

  

错误页面始终以“/”开头

控制器进入:

 @Controller public class RedirectAccessDenied { @RequestMapping(value = "/accessDeniedPage.htm", method = RequestMethod.GET) public String redirectAccessDenied(Model model) throws IOException, ServletException { System.out.println("############### Redirect Access Denied Handler!"); return "403"; } } 

这里403是我的JSP名称。

Spring Security使用AuthenticationEntryPoint对象来决定用户需要身份validation时要执行的操作。 您可以创建自己的AuthenticationEntryPoint bean( 请参阅javadoc ),然后在http元素中设置entryPoint属性:

  

但是,默认情况下,form-login元素会创建一个LoginUrlAuthenticationEntryPoint,它会将所有未经身份validation的用户重定向到登录页面,因此您不必自己执行此操作。 实际上,您发布的日志声称它将用户转发到身份validation入口点:“拒绝访问(用户是匿名的);重定向到身份validation入口点”。

我想知道问题是你关闭了登录url的filter链。 而不是将filter设置为none,这意味着完全绕过Spring安全性,尝试保持filter开启但允许不受限制的访问,如下所示:

  

如果仍然没有帮助,请发布日志的其余部分,以便我们可以看到请求转移到入口点后会发生什么。

以编程方式解决:

 @Order(1) @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { // // ... // @Override protected void configure(HttpSecurity http) throws Exception { http.exceptionHandling().accessDeniedHandler(new AccessDeniedHandlerImpl() { @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { super.handle(request, response, accessDeniedException); accessDeniedException.printStackTrace(); } }); // // ... // } } 

你能检查你的web.xml是否支持转发请求?

errorPage是一个FORWARD请求,主要在web.xml中,我们只支持REDIRECTS。 只是想到你的代码对我来说没问题。

编辑

一个不同的观点,这只是从工作代码中获取的。 看看Authenticated Voter类

禁用注释

   

绕过filter

                

自定义决策选民

  

访问决策管理器

           

validationexception处理程序

     /?login_error=t  /changePassword  /?login_error=t  /?login_error=t    

看起来spring试图重定向尚未登录到登录页面的用户,即“/ index”,但这本身就是受保护的URL。

另一种可能性是,它试图显示/public/403.html,但这又受到安全配置的保护。

您可以添加以下条目并尝试吗?