【问题标题】:GWT RPC with Spring role-base SecurityGWT RPC 与 Spring 基于角色的安全性
【发布时间】:2014-07-20 02:18:03
【问题描述】:

我的问题很简单“在使用 Spring 安全性和 GWT RPC 时会有什么问题吗?”。

我想在 GWT 的 RPC 方法上使用 Spring 的方法级别安全性。例如:在我的 ServiceImpl 类中,我使用了Expression-Based Access Control,如下所示。

@PreAuthorize("hasRole('ROLE_ADMIN')")
public final String getById(Long id) {
    .........
}

如果未授权角色访问用户尝试访问处理此 rpc 方法的页面,则会引发异常并且不会重定向到我的拒绝访问页面。我不知道为什么不去我的拒绝访问页面?我的控制台出现异常

抛出了一个意外的异常:org.springframework.security.access.AccessDeniedException: Access is denied

我配置为this 准确回答但仍然出现错误。如果我错了请纠正我“我认为这个问题可能是由于 gwt 的 RPC”因为非 rpc 方法很好并且重定向到我的 unSecure.html 。我花了大约 3 天的时间来解决这个错误。在 onFailure(Throwable catch) 我的异步方法展示

500 服务器调用失败;详情见服务器日志

我想展示我的配置。


spring-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:sec="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security.xsd">

<sec:global-method-security
    secured-annotations="enabled" pre-post-annotations="enabled" />
<sec:http auto-config="false" entry-point-ref="authenticateFilterEntryPoint">
    <sec:access-denied-handler ref="accessDeniedHandler" />
    <sec:intercept-url pattern="/login.html" />

    <sec:logout logout-url="/logout.html" logout-success-url="/login.html"
        invalidate-session="true" />
    <sec:form-login login-page="/login.html"
        login-processing-url="/login_check" authentication-failure-url="/login.html?error=1" />

    <sec:session-management invalid-session-url="/login.html">
        <sec:concurrency-control max-sessions="50"
            error-if-maximum-exceeded="true" />
    </sec:session-management>
    <sec:remember-me key="mykey"
        token-validity-seconds="604800" />
</sec:http>

<beans:bean id="authenticateFilterEntryPoint"
    class="mypackage.common.security.SessionTimeoutEntryPoint">
    <beans:property name="loginFormUrl" value="/login.html" />
</beans:bean>

<beans:bean id="accessDeniedHandler"
    class="mypackage.common.security.AccessDeniedEntryPoint">
    <beans:property name="errorPage" value="/unSecure.html" />
</beans:bean>

<beans:bean
    class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <beans:property name="defaultErrorView" value="uncaughtException" />
    <beans:property name="excludedExceptions"
        value="org.springframework.security.access.AccessDeniedException" />

    <beans:property name="exceptionMappings">
        <beans:props>
            <beans:prop key=".DataAccessException">dataAccessFailure</beans:prop>
            <beans:prop key=".NoSuchRequestHandlingMethodException">resourceNotFound</beans:prop>
            <beans:prop key=".TypeMismatchException">resourceNotFound</beans:prop>
            <beans:prop key=".MissingServletRequestParameterException">resourceNotFound</beans:prop>
        </beans:props>
    </beans:property>
</beans:bean>

<beans:bean id="authenticationUserService"
    class="mypackage.common.security.AuthenticationUserService" />

<sec:authentication-manager>
    <sec:authentication-provider
        user-service-ref="authenticationUserService">
        <sec:password-encoder hash="md5" />
    </sec:authentication-provider>
</sec:authentication-manager>

<beans:bean id="authLoggerListener"
    class="org.springframework.security.authentication.event.LoggerListener" />
<beans:bean id="eventLoggerListener"
    class="org.springframework.security.access.event.LoggerListener" />

AccessDeniedEntryPoint.java

public class AccessDeniedEntryPoint extends org.springframework.security.web.access.AccessDeniedHandlerImpl {
private static final Logger logger = LoggerFactory.getLogger(AccessDeniedEntryPoint.class);

@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
        AccessDeniedException accessDeniedException) throws IOException, ServletException {
    super.handle(request, response, accessDeniedException);

}
}

SessionTimeoutEntryPoint.java

public class SessionTimeoutEntryPoint extends LoginUrlAuthenticationEntryPoint {

@Override
public final void commence(final HttpServletRequest request, final HttpServletResponse response,
        final AuthenticationException authException) throws IOException, ServletException {
    super.commence(request, response, authException);
}
}

所以,当未授权角色用户访问此方法时,我想获得 unSecure.html。我真的很感激你的任何建议。对不起我的长问题。我不想再撞我的头了!谢谢。

【问题讨论】:

  • 我还使用了 Spring Security 的登录安全性,正如我所描述的,效果很好。但是对于方法级别的安全性,我做错了什么?这不会重定向到我的 unSecure.html 页面,除非以 AccessDenied 身份登录控制台。

标签: java spring gwt spring-security gwt-rpc


【解决方案1】:

就像我上次的回复一样,我很久以前就用过这个。在我的情况下,我没有总是处理我委托给处理程序的 url。

我的意思是,如果你想将 GWT-RPC 与 Spring-Security 集成,我做的第一件事就是从我的 GWT 应用程序尝试登录 Spring。

所以你需要做的第一件事是创建一个RPC-CALL (here official documentation) 用于登录。

我发现注释@RemoteServiceRelativePath("examplelogin.rpc") 很有用,所以如果你使用它,你可以利用路径,然后,在spring-security.xml 中,你可以通过这些路径过滤请求(参见下面的更新示例)。

不确定为什么要将 GWT-RPC 与 Spring-Security 集成,然后指定 /login.html(应该是 rpc 调用,之前描述过而不是 html?但也许你正在使用自己的 MVP 和 GWT,所以我并不是说这是错误的,只是让我感到惊讶:))。

阅读您的代码,我没有发现任何问题,但在我的情况下,我有一些不同之处:

....
<http use-expressions="true" entry-point-ref="http401UnauthorizedEntryPoint">

    <intercept-url pattern="/yourProject/public.rpc" access="permitAll" />
    <intercept-url pattern="/yourProject/examplelogin.rpc" access="hasRole('ROLE_ADMIN')" />

    <form-login authentication-success-handler-ref="authenticationSuccessHandler"
        authentication-failure-handler-ref="authenticationFailureHandler"/>


    ..... //logout, session-management, custom-filters....

    <beans:bean id="http401UnauthorizedEntryPoint" 
                class="your.project.Http401UnauthorizedEntryPoint" />
    <beans:bean id="authenticationSuccessHandler" 
                class="your.project.GWTAuthenticationSuccessHandler"/>
    <beans:bean id="authenticationFailureHandler" 
                class="your.project.GWTAuthenticationFailureHandler"/>
</http>
....

您特别询问了将Spring-Security 与GWT-RPC 一起使用的可能性(这是因为我在&lt;intercept-url&gt; 标签中放置了.rpc 网址)

注意

答案是肯定的,我已经做到了(三年前,但我做到了:))

我认为您的问题的关键是:

  • 为 RPC 调用或 /login.html 指定拦截器 url

  • 像我一样委托处理程序(小心,也许你做得很好 并且错误在其他部分,但至少我在示例中确实喜欢它 工作)。

很抱歉没有直接向您显示错误,我希望这些答案会有所帮助。

谢谢。

【讨论】:

  • 谢谢兄弟!并感谢您之前对我的问题的回答:-)。目前,如何为 RPC 调用指定拦截器?
  • 因为我使用方法级安全性作为@PreAuthorize("hasRole('ROLE_ADMIN')")。
  • 您将表单登录错误委托为 &lt;form-login authentication-success-handler-ref="authenticationSuccessHandler" authentication-failure-handler-ref="authenticationFailureHandler"/&gt; 。如果是这样,我该如何处理我的 AccessDenied 处理程序?
  • 你同意我认为这个问题可能是由于gwt的RPC吗?
  • 哦!抱歉,可能我没有直接回答,因为我仍然在 Hibernate 上“迷路”。我认为最好的选择是你创建一个尽可能简单的项目(逐步描述你的场景和你的要求),然后给我(你可以在我的个人资料中查看我的电子邮件)一个链接到你的 github,我在我的机器。如果可以的话,我会很乐意提供帮助:)
猜你喜欢
  • 1970-01-01
  • 2013-03-21
  • 2011-05-12
  • 1970-01-01
  • 2017-04-04
  • 2012-03-18
  • 2019-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多