1

My question is quite simple "Can have any problems when using Spring security and GWT RPC ?" .

I would like to use spring's method level security on GWT's RPC methods.For instance : at my ServiceImpl class , I used Expression-Based Access Control as below.

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

If un-authorize role access users trying to access page dealing with this rpc method , exception was thrown and don't redirect to my access-denied page. I have no idea why doesn't go to my access-denied page ? I got an exception at my console as

threw an unexpected exception: org.springframework.security.access.AccessDeniedException: Access is denied

I configured as this answer exactly but still getting above error.Please correct me if I am wrong "I think this problem may due to gwt's RPC" because non-rpc methods were fine and redirect to my unSecure.html . I spend about 3 days for this error . At onFailure(Throwable caught) of my asynchronous method show

500 The call failed on the server; see server log for details

I want to show my configurations .


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);
}
}

So , I would like to get unSecure.html when un-authorize role users access this method. I would really appreciated any of your suggestions. Sorry for my long question. I don't want to hit my head anymore ! Thanks.

Community
  • 1
  • 1
Cataclysm
  • 7,592
  • 21
  • 74
  • 123
  • I also used login security with Spring Security as I described and that works fine. But for method level security , What am I wrong ? That does not redirect to my unSecure.html page except log in console as `AccessDenied`. – Cataclysm May 30 '14 at 10:46

1 Answers1

2

As in my last response, I used this long time ago. In my case instead of dealing always with urls I delegated into handlers.

I mean, if you want to integrate GWT-RPC with Spring-Security, the first thing that I did, was from my GWT app try to login against Spring.

So the first thing that you need to do is create a RPC-CALL (here official documentation) for login.

I found useful the annotation @RemoteServiceRelativePath("examplelogin.rpc"), so if you use it you can take advantage about the path, and then, in the spring-security.xml you can filter the request by those path (see the updated example below).

Not sure why you want to integrate GWT-RPC with Spring-Security and then you specify /login.html (should it be a rpc call, described befored instead of html? But maybe you are using your own MVP with GWT, so I am not saying that is wrong, only it surprises me :) ).

Reading your code I do not see something wrong, but in my case I have some differences:

....
<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>
....

You asked specifically about the possibility of using Spring-Security with GWT-RPC (that is the reason because in the <intercept-url> tags I place there the .rpc urls)

Note that the

The answer is yes, I have done it (three years ago, but I did :) )

I think here the keys for your problem are:

  • Specify the interceptor url for the RPC calls or your /login.html

  • Delegate on handlers like I did (be careful maybe you are doing well and the error is in other part, but at least I did like in the example and it worked).

Sorry for not showing you directly the error, I hope this answers will help.

Thanks.

apanizo
  • 628
  • 5
  • 11
  • Thank you brother ! and thanks for your previous answer of my question :-) . At now , how to specify the interceptor for RPC calls ? – Cataclysm May 30 '14 at 11:22
  • because I am using method level security as `@PreAuthorize("hasRole('ROLE_ADMIN')")`. – Cataclysm May 30 '14 at 11:24
  • You delegate form login error as `` . If so how can I do for my **AccessDenied handler** ? – Cataclysm May 30 '14 at 11:34
  • And do you agree for ***I think this problem may due to gwt's RPC*** ? – Cataclysm May 30 '14 at 11:37
  • I updated my answer. regarding to your first and second comment. About the third and fourth one, I wrote an example of handler's name. Probably if you replace them by your owns, should be fine. – apanizo May 30 '14 at 11:42
  • Pls don't be mind brother , I was troubled in this error for a long time and I haven't anyone to ask . So , I request suggestions on **SO** . As your example , should I remove method level securing as `@PreAuthorize("hasRole('ROLE_ADMIN')")` ? – Cataclysm May 30 '14 at 11:52
  • Man! Do not worry! Ask whatever you want all the times what you need. If I know the solution, I'll help :). Regarding to your last comment, I think I have never used '@PreAuthorize' annotation, but I am not positive. – apanizo May 30 '14 at 14:19
  • The thing that I am trying to say, all your classes which implement the rpc calls should not have any information of Spring-Security, this is a thing done in your server. – apanizo May 30 '14 at 14:47
  • for your last comment ..yes I know brother, and .... my question was mainly for **method level securing** but you described informations and samples for **url securing or url intercepting**. But anyway ,thanks for your help. – Cataclysm May 31 '14 at 04:07
  • 1
    Oh! Sorry, probably I am not answering directly because I am still 'lost' on Hibernate. I think the best option is you create a project as much simpler as possible (describing step by step your scenario and your requirements), and send me (you can check my email in my profile) a link into your github, and I test on my machine. If I can, I'll help with pleasure :) – apanizo May 31 '14 at 21:05