GWT and spring security integration,DelegatingFilterProxy has a dead loop

463 views
Skip to first unread message

Alex Luya

unread,
Jul 4, 2016, 11:02:38 PM7/4/16
to GWT Users

There is a pure GWT solution here:GWT Spring Security Integration (PURE GWT, NO JSP)

1,Do not use http element at all (http tag from config namespace)

2,Define your AuthenticationRpcService

3,Add AuthenticationRpcService.authenticate(user,password) method

4,Inject into AuthenticationServiceImpl AuthenticationProvider bean from security-context.xml

5,Implement AuthenticationRpcService.authenticate(user,password) as :

User user = new User(login, password, true, true, true, true, new ArrayList<GrantedAuthority>());
Authentication auth = new UsernamePasswordAuthenticationToken(user, password,
        new ArrayList<GrantedAuthority>());
try {
    auth = this.authenticationProvider.authenticate(auth);
} catch (BadCredentialsException e) {
    throw new ClientSideBadCredentialsException(e.getMessage(), e);
}
SecurityContext sc = new SecurityContextImpl();
sc.setAuthentication(auth);
SecurityContextHolder.setContext(sc);

6,Ensure that spring security filter chain is executed during processing of each your GWT RPC call (to be sure that SecurityContext populated into SecurityContextHolder).

For this sixth step, added blow to web.xml:

<!-- Spring Security related configuration -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/dp_web/service/*</url-pattern>
</filter-mapping>

and blow to applicationContext.xml:

<bean id="springSecurityFilterChain" class="org.springframework.web.filter.DelegatingFilterProxy"/>

Then call authentication service,got blow error:

<p>Problem accessing /service/authenticate. Reason:
<pre>    Server Error</pre></p><h3>Caused by:</h3><pre>java.lang.StackOverflowError
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)

As you can see there is a dead loop that causes StackOverflowError,and I am not good at spring,after two hours googling,can't figure out a way to solve this problem,so can anybody help me?Thanks.

Alexander Leshkin

unread,
Jul 5, 2016, 4:38:31 AM7/5/16
to GWT Users

On Tuesday, July 5, 2016 at 6:02:38 AM UTC+3, Alex Luya wrote:

and blow to applicationContext.xml:

<bean id="springSecurityFilterChain" class="org.springframework.web.filter.DelegatingFilterProxy"/>


I think this causes recursion. Try to remove this bean declarion. Spring security should internally create bean with name springSecurityFilterChain.
In this case, the bean is named "springSecurityFilterChain", which is an internal infrastructure bean created by the namespace to handle web security. Note that you should not use this bean name yourself. Once you’ve added this to your web.xml, you’re ready to start editing your application context file. Web security services are configured using the <http> element.


Alex Luya

unread,
Jul 5, 2016, 6:25:39 AM7/5/16
to GWT Users
Does this mean if add  added blow to web.xml:
<!-- Spring Security related configuration -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/dp_web/service/*</url-pattern>
</filter-mapping>

I must use <http> to configure something in applicationContext.xml?

In my case,I removed above stuff from web.xml,added 

@Secured({"ROLE_USER"})

to class ServiceBase and let all other service inherit from it,and added this:

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

to applicationContext.xml,and remove all other spring security related from it,rerun my web app,all inherited service invoking
give 500 error,so security mechanism do works, but obviously,following code is not enough:

User user = new User(login, password, true, true, true, true, new ArrayList<GrantedAuthority>());
Authentication auth = new UsernamePasswordAuthenticationToken(user, password,
        new ArrayList<GrantedAuthority>());
try {
    auth = this.authenticationProvider.authenticate(auth);
} catch (BadCredentialsException e) {
    throw new ClientSideBadCredentialsException(e.getMessage(), e);
}
SecurityContext sc = new SecurityContextImpl();
sc.setAuthentication(auth);
SecurityContextHolder.setContext(sc);

So question is what else I should do except:

1,add @Secured({"ROLE_USER"}) to parent service
2,add <security:global-method-security secured-annotations="enabled" /> to applictionContext.xml

Alexander Leshkin

unread,
Jul 5, 2016, 7:44:54 AM7/5/16
to GWT Users
On Tuesday, July 5, 2016 at 1:25:39 PM UTC+3, Alex Luya wrote:
Does this mean if add  added blow to web.xml:
<!-- Spring Security related configuration -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/dp_web/service/*</url-pattern>
</filter-mapping>

I must use <http> to configure something in applicationContext.xml?

Yes. If you want to use default implementaion of the "filter chain", you have to use namespaces (<http>) for configuration or you may use JavaConfig aproach.
 

In my case,I removed above stuff from web.xml,added 

@Secured({"ROLE_USER"})

to class ServiceBase and let all other service inherit from it,and added this:

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

to applicationContext.xml,and remove all other spring security related from it,rerun my web app,all inherited service invoking
give 500 error,so security mechanism do works, but obviously,following code is not enough:

User user = new User(login, password, true, true, true, true, new ArrayList<GrantedAuthority>());
Authentication auth = new UsernamePasswordAuthenticationToken(user, password,
        new ArrayList<GrantedAuthority>());
try {
    auth = this.authenticationProvider.authenticate(auth);
} catch (BadCredentialsException e) {
    throw new ClientSideBadCredentialsException(e.getMessage(), e);
}
SecurityContext sc = new SecurityContextImpl();
sc.setAuthentication(auth);
SecurityContextHolder.setContext(sc);

So question is what else I should do except:

1,add @Secured({"ROLE_USER"}) to parent service
2,add <security:global-method-security secured-annotations="enabled" /> to applictionContext.xml



When you removed spring security filter-chain stuff, ability to inject SecurityContext to HttpRequest has been removed too (that's what one of the security filters does). 
So all requests handled on behalf of Anonymous user (even after authentication in RPC service).

I suggest to use separated page for "plain" login HTML form without gwt rpc. Thus, you can use default form login support from spring security.
Then, you should configure access rules for http requests (by using <http> namespace or JavaConfig... there is a lot of info and samples):

1. Allow login page for all.
2. And restrict all other URLs for authenticated only.

And, there is some example with custom implementation of the AuthenticationProvider [1] if you do not want to implement separated login page.

Reply all
Reply to author
Forward
0 new messages