Friday, December 13, 2013

Securing an existing REST service via SAML 2.0 Bearer Assertion Grant type

Usecase

A web application is secured with SAML SSO using WSO2 Identity Server 4.5.0 (IS) as the SAMLSSO provider.

After authenticating with SAMLSSO, user tries to access a REST service secured with OAuth, which is hosted in WSO2 Application Server 5.2.0 (AS). But he should not have to reauthenticate.

The web application should be able to exchange the received SAML Token (i.e. SAML Assertion) for an OAuth token, and send it to the REST service, which will then validate it with the IS. 

I have created a sample to demonstrate this usecase. Following is how to try it:

Configuring the WSO2 Identity Server

1. Download WSO2 Identity Server 4.5.0 [1] and extract it (wso2is-4.5.0.zip).

2.In wso2is-4.5.0/repository/conf/identity.xml locate the following config block. Make Enabled=true. By default it's false.

<AuthorizationContextTokenGeneration>        
            <Enabled>true</Enabled>
            <TokenGeneratorImplClass>org.wso2.carbon.identity.oauth2.authcontext.JWTTokenGenerator</TokenGeneratorImplClass>
            <ClaimsRetrieverImplClass>org.wso2.carbon.identity.oauth2.authcontext.DefaultClaimsRetriever</ClaimsRetrieverImplClass>
            <ConsumerDialectURI>http://wso2.org/claims</ConsumerDialectURI>
            <SignatureAlgorithm>SHA256withRSA</SignatureAlgorithm>
            <AuthorizationContextTTL>15</AuthorizationContextTTL>
        </AuthorizationContextTokenGeneration>

3. Run the server by executing wso2is-4.5.0/bin/wso2carbon.sh if on a Unix based systems, or /bin/wso2carbon.bat if on Windows.

4. Access the server by giving https://localhost:9443/carbon on your web browser. And log in as "admin":"admin"(username:password)

SAMLSSO Configuration...

5. On the home page, under Manage section, click "SAML SSO" and then click "Register New Service Provider".

6. Fill following details on the registration page:

* Issuer: SSOSampleApp
* Assertion Consumer URL: http://localhost:8080/SSOSampleApp/acs
* Select Enable Response Signing 
* Select Enable Assertion Signing 

* Select Enable Single Logout.
* Select Enable Audience Restriction
* Add Audience "https://localhost:9443/oauth2/token"

Finally click "Register".


OAuth Configuration...

7. Click OAuth under Manage section (right after SAMLSSO), then click "Register New Application"

8. Fill the form with following:

Application Name: SSOSampleApp
Unselect Code, Implicit, Password, Client Credential, Refresh Token

Finally click "Add"


9. Some settings of this new application will be needed when configuring our sample web application. Click "SSOSampleApp" on the OAuth page, you will be presented with the "Application Settings", copy Client Id, Client Secret.


Trusted Identity Providers Configuration...

10. Click "Trusted Identity Providers" (in the "Configure tab") and then click "Add New Trusted Identity Provider"

11. Fill the details as follows:

Identity Provider Name: wso2is
Identity Provider Issuer: https://localhost:9443/samlsso
Identity Provider Url: https://localhost:9443
Identity Provider Public Certificate: upload certificate

To create the public certificate, go to wso2is-4.5.0/repository/resources/security and execute following command.

keytool -export -alias wso2carbon -file wso2carbon.crt -keystore wso2carbon.jks -storepass wso2carbon



Configuring the Application Server

1. Download WSO2 Application Server 4.5.0 [2] and extract it (wso2as-5.2.0.zip)

I have used a sample that comes packed with AS as the existing REST service. Let's follow below steps to deploy it:

2. Go to wso2as-5.2.0/samples/Jaxws-Jaxrs/jaxrs_basic. README in that folder explains what this app does. I'll be using the /customers/name/ operation, which will return the hard-coded value "Isuru Suriarachchi".

3. Run "ant". This will deploy the jaxrs_basic app in WSO2 AS at wso2as-5.2.0/repository/deployment/server/webapps/

4. Copy org.wso2.carbon.sample.oauth.filter-1.0.0.jar [bin][src] to wso2as-5.2.0/repository/components/lib/

5. Copy org.wso2.carbon.identity.oauth.stub_4.2.0.jar [bin] to wso2as-5.2.0/repository/components/dropins/

6. Add following filter to wso2as-5.2.0/repository/deployment/server/webapps/jaxrs_basic/WEB-INF/web.xml

<filter>
        <filter-name>OAuthValidationFilter</filter-name>
        <filter-class>org.wso2.carbon.sample.oauth.filter.OAuthTokenValidatorFilter</filter-class>
       
        <init-param>
         <param-name>Oauth2TokenValidationServiceURL</param-name>
         <param-value>https://localhost:9443/services/OAuth2TokenValidationService</param-value>
        </init-param>
       
        <init-param>
         <param-name>IdPUsername</param-name>
         <param-value>admin</param-value>
        </init-param>
       
        <init-param>
         <param-name>IdPPassword</param-name>
         <param-value>admin</param-value>
        </init-param>
    </filter>
   
    <filter-mapping>
        <filter-name>OAuthValidationFilter</filter-name>
        <url-pattern>/services/*</url-pattern>
    </filter-mapping>

7. Change the port "offset" to "1" in wso2as-5.2.0/repository/conf/carbon.xml.

8. Finally, run the server as we did with IS, using the wso2server.sh/bat script inside the bin folder.

Configuring the Sample Web App

1. Open SSOSampleApp.war [bin][src] using an archive manager and change following properties located in /WEB-INF/classes/sample.properties

KeyStore=[path to]/wso2as-5.2.0/repository/resources/security/wso2carbon.jks

ConsumerUrl=http://localhost:8080/SSOSampleApp/acs
(Change the above URL according to the application server you are using. This the hostname:port of the Tomcat instance I'm running)

OAuth.client.id=[Client id you copied at step 9 of configuring the IS]
OAuth.client.secret=[Client secret you copied at step 9 of configuring the IS]

2 . Deploy SSOSampleApp.war in your application server and run the server.

Let's test this...
1. Access the webapp deployed in the application server via the web browser: localhost:8080/SSOSampleApp/

2. It gets redirected to IS login page. Give "admin":"admin" (username:password) and click "Sign In"


Browser get redirected back to the web app. Now we have successfully authenticated via SAML SSO.



To do the REST call to the sample app we deployed in AS... Click "here".

You'll see the response as Isuru Suriarachchi.


Tomcat console will display the OAuth token received when we exchanged the SAML token.


AS console will display the result of the OAuth token validation.


Ref:
[1] http://wso2.com/products/identity-server/
[2] http://wso2.com/products/application-server/

No comments: