我一直在试用这个应用程序的'方法级'安全性,我一直在努力。我们的想法是确保使用DWR从表示层调用的方法。 现在,我尝试在我的方法上添加以下注释:
@PreAuthorize("isAuthenticated() and hasRole('ROLE_CUSTOMER')")
我的安全上下文中的相应条目:
<global-method-security pre-post-annotations="enabled" />
在类似的路线上,我尝试过@Secured注释:
@Secured({"ROLE_CUSTOMER" })
我的安全上下文中的相应条目:
<global-method-security secured-annotations="enabled" />
理想情况下,我希望如果用户未经过身份验证,则应将其重定向到“登录”页面,并且不应检查“ROLES”。在这种情况下,即使对于未经身份验证的用户,此方法调用也会导致“AccessDeniedException”。在这种情况下,我需要它将用户重定向到登录页面。
为了推进它,我甚至尝试通过创建自定义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"/>
答案 0 :(得分:0)
我对DWR不太熟悉,但我知道它是一种RPC机制。问题是客户端javascript发送的RPC请求不是导航浏览器的用户发起的常规页面请求。对此类RPC请求的响应不可能使浏览器离开当前页面,因为响应是由您的javascript代码而不是浏览器处理的。
你能做的是:
AccessDeniedException
以某种形式传播到客户端,您可以尝试从javascript代码处理它,例如通过弹出登录对话框,并在一个提交用户的凭据AJAX请求。 (在这种情况下,请确保保存返回的会话ID,并在每次后续请求时将其发回。)答案 1 :(得分:0)
我有兴趣看到你的security.xml
文件的其余部分(具体来说,是<http>
元素),因为如果每个用户被拒绝,它会告诉我您有一个<intercept-url>
属性,它会覆盖对您的控制器类的调用。如果没有,增加的信息可能有助于解决问题。
假设到目前为止我已离开,另一个可能的错误点可能是指定的access-denied-page
本身 - 如果它的路径是受保护的路径(即<intercept-url>
),或者它不是'如果指定,您可能会看到您说的错误。
当然,我也不熟悉DWR,所以我显然假设一个标准的Spring MVC框架......
答案 2 :(得分:0)
好的,我没有成功找到为什么会遇到AccessDeniedException。无论如何,我一直在努力,直到找到原因。以下是我采取的几种方法:
1)正如Zagyi所说,我能够将AccessDenied Exception传播到客户端。我可以创建一个异常处理程序并将用户重定向到登录页面。
然而,我采取了一种不同的方法(可能不是最优的方法,但现在似乎有效。这就是我所做的:
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)这似乎现在效果很好。我还在测试它,看看这是否在某处失败。
不胜感激任何投入。