I am trying to implement OAuth-based security for a set of Seam resources that are exposed via a RESTful interface. I am using Seam 2.2.0 for my resources and RESTEasy 1.2 for the REST related stuff.
The OAuth token setup process has been implemented and even though it's not feature complete, one may get hold of a proper access token.
My next task is to let the external application access the resources. If the resource call is accompanied with a valid access token, that call should be made as the user that is associated with that particular token.
The problem is that I can't figure out how to set up the proper Seam Identity context for each resource call (web service request).
The application's web.xml file
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- Seam listener --> <listener> <listener-class>org.jboss.seam.servlet.SeamListener</listener-class> </listener> <!-- The OAuth Servlet handles token exchange --> <servlet> <servlet-name>OAuth</servlet-name> <servlet-class>org.jboss.resteasy.auth.oauth.OAuthServlet</servlet-class> </servlet> <!-- This will be the base for the token exchange endpoint URL --> <servlet-mapping> <servlet-name>OAuth</servlet-name> <url-pattern>/oauth/*</url-pattern> </servlet-mapping> <context-param> <param-name>oauth.provider.provider-class</param-name> <param-value>com.mydomain.oauth.OAuthProvider</param-value> </context-param> <context-param> <param-name>oauth.provider.tokens.request</param-name> <param-value>/request_token</param-value> </context-param> <context-param> <param-name>oauth.provider.tokens.access</param-name> <param-value>/access_token</param-value> </context-param> <!-- The OAuth Filter handles authentication for protected resources --> <filter> <filter-name>OAuth Filter</filter-name> <filter-class>org.jboss.resteasy.auth.oauth.OAuthFilter</filter-class> </filter> <!-- This defines the URLs which should require OAuth authentication for your protected resources --> <filter-mapping> <filter-name>OAuth Filter</filter-name> <url-pattern>/seam/resources/*</url-pattern> </filter-mapping> <servlet> <servlet-name>Seam Resource Servlet</servlet-name> <servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Seam Resource Servlet</servlet-name> <url-pattern>/seam/resources/*</url-pattern> </servlet-mapping> </web-app>
Debugging a web service call, one can see that the RESTEasy OAuthFilter is executed and it:
- validates the access token
- gets all user info from the token (name and roles)
modifiesthe HTTP request so that the getUserPrincipal() method returns the user associated with the token
- calls the next filter in the request filter chain
This doesn't seem to be enough though. When the Seam resource servlet a bit later tries to dispatch the resource method, it fails because there is no user logged in. The resource method is annotated with @Restrict(
Is there anyone out there that has any experience with the combination Seam, RESTEasy and OAuth? How should one think to make this identity/login handling work on a per request/token basis? Maybe I've missed something very basic or fundamental regarding Seam/REST integration?
Thanks in advance for any information that can make me get a bit further implementing this.