Sunday, November 16, 2014

Verify OpenID Connect IDToken Signature in WSO2 Identity Server

WSO2 Identity Server 5.1.0 will be released soon and with that hope to get more OpenID Connect compliance feature than previous WSO2 Identity Server releases. ID Token is the key factor of OpenID Connect core specification [1]. Previous releases of WSO2 Identity Server up to IS 5.0.0 did not provide signed ID Token and which is bit hard to manage in production environment. With Identity Server 5.1.0 release we are going to provide signed ID Token to address some security vulnerabilities  in production environment.

Unsigned ID token contains only 2 portions separated by "."

<header>.<body>

Sample
eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhbGljZSIsImlzcyI6Imh0dHBzOlwvXC9jMmlkLmNvbSIsImlhdCI6MTQxNjE1ODU0MX0

Signed ID token contains 3 portions separated by "."

<header>.<body>.<signature>

Sample
eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhbGljZSIsImlzcyI6Imh0dHBzOlwvXC9jMmlkLmNvbSIsImlhdCI6MTQxNjE1ODU0MX0.iTf0eDBF-6-OlJwBNxCK3nqTUjwC71-KpqXVr21tlIQq4_ncoPODQxuxfzIEwl3Ko_Mkt030zJs-d36J4UCxVSU21hlMOscNbuVIgdnyWhVYzh_-v2SZGfye9GxAhKOWL-_xoZQCRF9fZ1j3dWleRqIcPBFHVeFseD_64PNemyg

If you want to see exact json values, you can do Base64 decode for <header>.<body>

This is a simple java program to validate ID token signature against default wso2carbon.jks public key in WSO2 products.

package org.sample;

import java.io.InputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.interfaces.RSAPublicKey;

import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jwt.SignedJWT;

public class ValidateRSASignature {

    public static void main(String[] args) throws Exception {
        RSAPublicKey publicKey = null;
        InputStream file = ClassLoader
                .getSystemResourceAsStream("wso2carbon.jks");
        KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
        keystore.load(file, "wso2carbon".toCharArray());

        String alias = "wso2carbon";

        // Get certificate of public key
        Certificate cert = keystore.getCertificate(alias);
        // Get public key
        publicKey = (RSAPublicKey) cert.getPublicKey();

        // Enter JWT String here
        String signedJWTAsString = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhbGljZSIsImlzcyI6Imh0d";

        SignedJWT signedJWT = SignedJWT.parse(signedJWTAsString);

        JWSVerifier verifier = new RSASSAVerifier(publicKey);

        if (signedJWT.verify(verifier)) {
            System.out.println("Signature is Valid");
        } else {
            System.out.println("Signature is NOT Valid");
        }
    }
}

Configuration to switch between signed and unsigned ID tokens

With default configurations ID token is always signed if you want to switch off ID token signing please following configurations in identity.xml

<AuthorizationContextTokenGeneration>
                        <Enabled>true</Enabled>
                        <SignatureAlgorithm>NONE</SignatureAlgorithm>
</AuthorizationContextTokenGeneration>

Please Note:
By default WSO2 products ship with wso2carbon.jks. In wso2carbon.jks key store password is "wso2carbon" and certificate alias also "wso2carbon". In production environment we recommend to change those values.

Complete sample source attached here with all readME instructions. 

[1]http://openid.net/specs/openid-connect-core-1_0.html

[2]https://svn.wso2.com/wso2/interns/2013/gayan/org.sample.zip


Sunday, October 19, 2014

Obtain Access Token form WSO2 Identity Server Token Endpoints

Authorization Code Grant Type

https://localhost:9443/oauth2/authorize?
response_type=code&
client_id=0rhQErXIX49svVYoXJGt0DWBuFca&
redirect_uri=https%3A%2F%2Fmycallback

https://mycallback/?code=9142d4cad58c66d0a5edfad8952192

curl -v -X POST --basic
-u 0rhQErXIX49svVYoXJGt0DWBuFca:eYOFkL756W8usQaVNgCNkz9C2D0a
-H "Content-Type:application/x-www-form-urlencoded;charset=UTF-8" -k
-d "grant_type=authorization_code&
code=9142d4cad58c66d0a5edfad8952192&
redirect_uri=https://mycallback" https://localhost:9443/oauth2/token

Implicit Grant Type

https://localhost:9443/oauth2/authorize?response_type=token&
client_id=0rhQErXIX49svVYoXJGt0DWBuFca&
redirect_uri=https%3A%2F%2Fmycallback

https://mycallback/#access_token=cac93e1d29e45bf6d84073dbfb460&expires_in=3600

Resource Owner Password Credentials Grant Type

curl -v -X POST --basic
-u 0rhQErXIX49svVYoXJGt0DWBuFca:eYOFkL756W8usQaVNgCNkz9C2D0a
-H "Content-Type:application/x-www-form-urlencoded;charset=UTF-8" -k
-d "grant_type=password&
username=admin&password=admin"
https://localhost:9443/oauth2/token

{
"token_type":"bearer",
"expires_in":685,
"refresh_token":"22b157546b26c2d6c0165c4ef6b3f736",
"access_token":"cac93e1d29e45bf6d84073dbfb460"
}

Client Credentials Grant Type

curl -v -X POST --basic
-u 0rhQErXIX49svVYoXJGt0DWBuFca:eYOFkL756W8usQaVNgCNkz9C2D0a
-H "Content-Type:application/x-www-form-urlencoded;
charset=UTF-8" -k

-d "grant_type=client_credentials" https://localhost:9443/oauth2/token

Saturday, September 20, 2014

WSO2 Identity Server as a SCIM provider with secondary user store

WSO2 Identity Server [1] ship with embedded LDAP as  primary user store and you can plug any JDBC, LDAP, Active Directory user store as a secondary user store.

If you have primary user store only SCIM commands works as mentioned here [2]. If need to execute those commands for secondary user store follow these steps

Important: you have to put username and group name in following format 
'<user store domain>/username' and remember to use single quotes instead of double quotes.

1. Create User

curl -v -k --user admin:admin --data "{"schemas":[],"name":{"familyName":"gunasinghe","givenName":"hasinitg"},"userName":'JDBC/hasinitg',"password":"hasinitg","emails":[{"primary":true,"value":"hasini_home.com","type":"home"},{"value":"hasini_work.com","type":"work"}]}" --header "Content-Type:application/json" https://localhost:9443/wso2/scim/Users

Response

{"id":"2f4a6f3a-7a09-4826-9bde-6082c57a9e63","schemas":["urn:scim:schemas:core:1.0"],"name":{"familyName":"gunasinghe","givenName":"hasinitg"},"userName":"JDBC/hasinitg","emails":[{"value":"hasini_home.com","type":"home"},{"value":"hasini_work.com","type":"work"}],"meta":{"lastModified":"2014-09-14T22:20:23","location":"https://localhost:9443/wso2/scim/Users/2f4a6f3a-7a09-4826-9bde-6082c57a9e63","created":"2014-09-14T22:20:23"}}

2. Get User 

curl -v -k --user admin:admin https://localhost:9443/wso2/scim/Users/2f4a6f3a-7a09-4826-9bde-6082c57a9e63

Response

{"id":"2f4a6f3a-7a09-4826-9bde-6082c57a9e63","schemas":["urn:scim:schemas:core:1.0"],"name":{"familyName":"gunasinghe","givenName":"hasinitg"},"userName":"JDBC/hasinitg","emails":[{"value":"hasini_work.com","type":"work"},{"value":"hasini_home.com","type":"home"}],"meta":{"lastModified":"2014-09-14T22:20:23","created":"2014-09-14T22:20:23","location":"https://localhost:9443/wso2/scim/Users/2f4a6f3a-7a09-4826-9bde-6082c57a9e63"}}

3. List Users

curl -v -k --user admin:admin https://localhost:9443/wso2/scim/Users

Response

{"schemas":["urn:scim:schemas:core:1.0"],"totalResults":1,"Resources":[{"id":"2f4a6f3a-7a09-4826-9bde-6082c57a9e63","name":{"familyName":"gunasinghe","givenName":"hasinitg"},"userName":"JDBC/hasinitg","emails":[{"value":"hasini_work.com","type":"work"},{"value":"hasini_home.com","type":"home"}],"meta":{"lastModified":"2014-09-14T22:20:23","created":"2014-09-14T22:20:23","location":"https://localhost:9443/wso2/scim/Users/2f4a6f3a-7a09-4826-9bde-6082c57a9e63"}}]}

4. Update User

curl -v -k --user admin:admin -X PUT -d "{"schemas":[],"name":{"familyName":"gunasinghe","givenName":"hasinitg"},"userName":'JDBC/hasinitg',"emails":[{"value":"hasini@wso2.com","type":"work"},{"value":"hasi7786@gmail.com","type":"home"}]}" --header "Content-Type:application/json" https://localhost:9443/wso2/scim/Users/2f4a6f3a-7a09-4826-9bde-6082c57a9e63

Response

{"id":"2f4a6f3a-7a09-4826-9bde-6082c57a9e63","schemas":["urn:scim:schemas:core:1.0"],"name":{"familyName":"gunasinghe","givenName":"hasinitg"},"userName":"JDBC/hasinitg","emails":[{"value":"hasini@wso2.com","type":"work"},{"value":"hasi7786@gmail.com","type":"home"}],"meta":{"lastModified":"2014-09-14T22:38:47","location":"https://localhost:9443/wso2/scim/Users/2f4a6f3a-7a09-4826-9bde-6082c57a9e63","created":"2014-09-14T22:20:23"},"groups":[{"value":"2d639c4c-78e3-4f83-b12e-9ce23b90eeab","display":"JDBC/engineer"}]}

5. Delete User

curl -v -k --user admin:admin -X DELETE https://localhost:9443/wso2/scim/Users/2f4a6f3a-7a09-4826-9bde-6082c57a9e63 -H "Accept: application/json"

6. Filter User

curl -v -k --user admin:admin https://localhost:9443/wso2/scim/Users?filter=userNameEqJDBC/hasinitg

Response

{"schemas":["urn:scim:schemas:core:1.0"],"totalResults":1,"Resources":[{"id":"2f4a6f3a-7a09-4826-9bde-6082c57a9e63","name":{"familyName":"gunasinghe","givenName":"hasinitg"},"userName":"JDBC/hasinitg","emails":[{"value":"hasini_work.com","type":"work"},{"value":"hasini_home.com","type":"home"}],"meta":{"lastModified":"2014-09-14T22:20:23","created":"2014-09-14T22:20:23","location":"https://localhost:9443/wso2/scim/Users/2f4a6f3a-7a09-4826-9bde-6082c57a9e63"}}]}

7. Create Group

curl -v -k --user admin:admin --data "{"displayName": 'JDBC/engineer',"members": [{"value":"2f4a6f3a-7a09-4826-9bde-6082c57a9e63","display": 'JDBC/hasinitg'}]}" --header "Content-Type:application/json" https://localhost:9443/wso2/scim/Groups

Response

{"id":"2d639c4c-78e3-4f83-b12e-9ce23b90eeab","schemas":["urn:scim:schemas:core:1.0"],"displayName":"JDBC/engineer","members":[{"value":"2f4a6f3a-7a09-4826-9bde-6082c57a9e63","display":"JDBC/hasinitg"}],"meta":{"lastModified":"2014-09-14T22:33:42","created":"2014-09-14T22:33:42","location":"https://localhost:9443/wso2/scim/Groups/2d639c4c-78e3-4f83-b12e-9ce23b90eeab"}}

8. List Groups

curl -v -k --user admin:admin https://localhost:9443/wso2/scim/Groups

Response

{"schemas":["urn:scim:schemas:core:1.0"],"totalResults":1,"Resources":[{"id":"2d639c4c-78e3-4f83-b12e-9ce23b90eeab","displayName":"JDBC/engineer","members":[{"value":"2f4a6f3a-7a09-4826-9bde-6082c57a9e63","display":"JDBC/hasinitg"}],"meta":{"lastModified":"2014-09-14T22:33:42","created":"2014-09-14T22:33:42","location":"https://localhost:9443/wso2/scim/Groups/2d639c4c-78e3-4f83-b12e-9ce23b90eeab"}}]}


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

[2] https://docs.wso2.com/display/IS500/WSO2+Identity+Server+as+a+SCIM+Service+Provider