1

我一直在尝试我一直在研究的这个应用程序的“方法级别”安全性。这个想法是保护使用 DWR 从表示层调用的方法。现在,我尝试在我的方法中添加以下注释:

@PreAuthorize("isAuthenticated() and hasRole('ROLE_CUSTOMER')")

以及我的安全上下文中的相应条目:

<global-method-security pre-post-annotations="enabled" />

在类似的行中,我尝试了 @Secured 注释:

@Secured({"ROLE_CUSTOMER" })

以及我的安全上下文中的相应条目:

<global-method-security secured-annotations="enabled" />

理想情况下,我希望如果用户未通过身份验证,则应将他们重定向到“登录”页面,并且不应检查“角色”。在这种情况下,即使对于未经身份验证的用户,此方法调用也会导致“AccessDeniedException”。在这种情况下,我需要它将用户重定向到登录页面。

为了推进它,我什至尝试通过创建自定义 AccessDenied 处理程序来处理 accessdenied 异常。不幸的是,处理程序从未被调用,但抛出了异常。

这是配置:

<access-denied-handler ref="customAccessDeniedHandler"/>

这在同一文件中定义了相应的处理程序 bean。

仍然没有运气。accessdeniedhandler 永远不会被调用。

总结一下需求,我需要确保一种方法。如果此方法被调用,并且用户未经身份验证,则用户应该被重定向到“登录”页面(截至目前,该页面正在抛出 Accessdenied execption)。

感谢您的帮助人们..

编辑 1:这是来自安全上下文的片段:

<http>
    <intercept-url pattern="/*sign-in.do*" requires-channel="$secure.channel}" />
    .....
    ..... 
    .....
    <intercept-url pattern="/j_acegi_security_check.do" requires-channel="${secure.channel}" />

    <intercept-url pattern="/*.do" requires-channel="http"  />
    <intercept-url pattern="/*.do\?*" requires-channel="http" />
    <form-login login-page="/sign-in.do" authentication-failure-url="/sign-in.do?login_failed=1"
        authentication-success-handler-ref="authenticationSuccessHandler" login-processing-url="/j_acegi_security_check.do"/>

    <logout logout-url="/sign-out.do" logout-success-url="/index.do" />

    <session-management session-authentication-strategy-ref="sessionAuthenticationStrategy" />
        <access-denied-handler ref="customAccessDeniedHandler"/>
  </http>
    <beans:bean id="customAccessDeniedHandler" class="com.mypackage.interceptor.AccessDeniedHandlerApp"/>
4

3 回答 3

0

我对 DWR 不是很熟悉,但我知道它是一种 RPC 机制。问题是客户端javascript发送的RPC请求不是由浏览浏览器的用户发起的常规页面请求。对此类 RPC 请求的响应不可能使浏览器离开当前页面,因为响应是由您的 javascript 代码而不是浏览器处理的。

你可以做的是:

  1. 实现一种急切的身份验证:在允许用户访问发出 DWR(或任何类型的 RPC)请求的 webapp (URL) 之前,将用户重定向到一个简单的 .jsp 登录页面。
  2. 如果AccessDeniedException远程过程抛出的信息以某种形式传播到客户端,您可以尝试从 javascript 代码中处理它,例如通过弹出登录对话框,并在 AJAX 请求中提交用户的凭据。(在这种情况下,请确保保存返回的会话 ID,并将其与每个后续请求一起发回。)
于 2013-05-07T12:34:42.023 回答
0

我有兴趣查看您的security.xml文件的其余部分(特别是<http>元素),因为如果每个用户都被拒绝,它向我表明您有一个<intercept-url>属性可以覆盖对您的控制器类的调用。如果没有,添加的信息可能有助于阐明问题。

假设我到目前为止还很远,另一个可能的错误点可能是指定的access-denied-page本身——如果它的路径是受保护的路径(即 by <intercept-url>),或者如果没有指定,您可能会看到您所说的错误。

当然,我也对 DWR 不熟悉,所以我有点明显地假设一个标准的 Spring MVC 框架......

于 2013-05-07T16:56:49.903 回答
0

好的,我没有成功找到为什么我得到 AccessDeniedException。无论如何,我一直在努力解决它,直到找到原因为止。这是我采取的几种方法:

1)正如 Zagyi 所提到的,我能够将 AccessDenied 异常传播到客户端。我可以创建一个异常处理程序并将用户重定向到登录页面。

但是,我采用了不同的方法(这可能不是最佳的,但目前似乎可以工作。这就是我所做的:

1) 创建一个 DWRAjaxFilter 并仅映射到我感兴趣的远程对象。这将只有对这些远程方法的 DWR 调用被过滤器拦截。这是因为我不希望所有 DWR 公开的方法都用于登录。

   <create creator="spring" javascript="downloadLinksAjaxService">
       <param name="beanName" value="downloadLinksAjaxService" />
       <include method="methodOne" />
       <include method="methodTwo" />  
       <filter class="com.xyz.abc.interceptor.DwrAjaxFilter"></filter>
   </create>

2)这是实际的过滤器实现:

public class DwrSessionFilter implements AjaxFilter {
    public Object doFilter(final Object obj, final Method method,
            final Object[] params, final AjaxFilterChain chain)
            throws Exception {

        SecurityContext context = SecurityContextHolder.getContext();
        Authentication auth = context.getAuthentication();
        if (!auth.isAuthenticated()
                || auth.getAuthorities().contains(
                        new GrantedAuthorityImpl("ROLE_ANONYMOUS"))) {
            throw new LoginRequiredException("Login Required");
        } else {
            return chain.doFilter(obj, method, params);
        }
    }
}

3)这是客户端处理程序:

function errorHandler(message, exception){

                if(exception && exception.javaClassName == "org.directwebremoting.extend.LoginRequiredException") {

                  document.location.reload();
                }
            }

4)我还为 DWR 添加了异常映射器,以便我可以将 JAVA 异常转换为 JS 异常:

<convert match="java.lang.Exception" converter="exception">
            <param name='include' value='message'/>
        </convert> 

5)到目前为止,这似乎运作良好。我仍在测试这个,看看它是否在某个地方失败。

将不胜感激任何更多的投入。

于 2013-05-10T03:56:10.703 回答