Sunday, July 27, 2014

OPSS Trust - Identity Propagation over HTTP/S

When we are interacting with external systems over HTTP/S protocol, some times we need to exchange the identities (valid credentials) over protocol to authorize the requested action. Using OPSS trust between two different Weblogic domains, we can propagate identities across HTTP/S enabled applications by providing and validating tokens. The OPSS trust service uses identity asserter available in Weblogic.

Pre-requisites: Same identity should exists on both the domains.

OPSS Trust configuration steps:

Source Domain Configuration:

1. Create a certificate based on source domain and add it to Key Store
>keytool -genkeypair -alias <domainName> -keypass welcome1-keyalg RSA -dname "<domainName>" -keystore default-keystore.jks -storepass welcome1

2.Export source domain certificate
>keytool -export -alias <domainName> -file <domainName>.cer -keystore default-keystore.jks -storepass welcome1

3. Copy the generated default-keystore.jks to ${domain.home}/config/fmwconfig

4. Check the keystore service configured in the file jps-config.xml points to the generated default-keystore.jks

<serviceInstance name="keystore" provider="keystore.provider" location="./default-keystore.jks">
            <description>Default JPS Keystore Service</description>
            <property name="keystore.provider.type" value="file"/>
            <property name="keystore.file.path" value="./"/>
            <property name="keystore.type" value="JKS"/>
            <property name="keystore.csf.map" value="oracle.wsm.security"/>
            <property name="keystore.pass.csf.key" value="keystore-csf-key"/>
            <property name="keystore.sig.csf.key" value="sign-csf-key"/>
            <property name="keystore.enc.csf.key" value="enc-csf-key"/>
     </serviceInstance>

5. Create a map/key pair used to open the keystore and another map/key pair used to issue tokens. The following commands illustrate these operations using the OPSS script createCred:
  • connect("weblogic","welcome1","t3://localhost:7001")
  • createCred(map="oracle.wsm.security", key="keystore-csf-key", user="keystore", password="welcome1", desc="Keystore Password")
  • createCred(map="oracle.wsm.security", key="sign-csf-key", user="orakey", password="welcome1", desc="Signing key")
6. Add a grant like the following to the policy store, which allows the client application to use the trust service API:

<grant>
  <grantee>
    <codesource>    
<url>file:${oracle.deployed.app.dir}/<MyApp>${oracle.deployed.app.ext}</url>
    </codesource>
  </grantee>
  <permissions>
    <permission>          
<class>oracle.security.jps.service.trust.TrustServiceAccessPermission</class>
        <name>appId=*</name>
        <actions>issue</actions>
     </permission>
    </permissions>
</grant>

7. Weblogic Identity Asserter Configuration:
Copy the WebLogic identity asserter JAR jps-wls-trustprovider.jar to the location ${domain.home}/lib/mbeantypes,as illustrated by the following command, and then restart the WebLogic Server.

>cp ${common.components.home}/modules/oracle.jps_11.1.1/jps-wls-trustprovider.jar ${domain.home}/lib/mbeantypes

8. Reboot Weblogic server and Login to WLS console.

Navigate to Security Settings > Security Realms > myrealm > Providers Tab > Authentication, and click New to open the Create a New Authentication Provider dialog.

In that dialog, enter TrustServiceIdentityAsserter in the name box, and select TrustServiceIdentityAsserter from the pull-down in the type box; then click OK.

9. Trust service configuration:
Open $DOMAIN_HOME\config\fmwconfig\jps-config.xml

        <propertySet name="trust.provider.embedded">
            <property name="trust.aliasName" value="<domainName>"/>
            <property name="trust.issuerName" value="<domainName>"/>
            <property name="trust.clockSkew" value="60"/>
            <property name="trust.token.includeCertificate" value="false"/>
            <property name="trust.token.validityPeriod" value="1800"/>
            <property name="trust.provider.className" value="oracle.security.jps.internal.trust.provider.embedded.EmbeddedProviderImpl"/>
        </propertySet>

10. Include $WLS_HOME\oracle_common\modules\oracle.jps_11.1.1\jps-api.jar in application classpath and add following code to application generate token.

public static final String AUTH_TYPE_NAME = "OIT";
String user = "weblogic"; 
URL url = "http://host:port/destinationApp"; 

JpsContextFactory ctxFactory = JpsContextFactory.getContextFactory();
JpsContext jpsCtx = ctxFactory.getContext();
final TrustService trustService = jpsCtx.getServiceInstance(TrustService.class);
final TokenManager tokenMgr = trustService.getTokenManager();
final TokenContext ctx = tokenMgr.createTokenContext(
    TokenConfiguration.PROTOCOL_EMBEDDED);
UsernameToken ut = WSSTokenUtils.createUsernameToken("wsuid", user);
GenericToken gtok = new GenericToken(ut);
ctx.setSecurityToken(gtok);
ctx.setTokenType(SAML2URI.ns_saml);
Map<String, Object> ctxProperties = ctx.getOtherProperties();
ctxProperties.put(TokenConstants.CONFIRMATION_METHOD,
    SAML2URI.confirmation_method_bearer);
AccessController.doPrivileged(new PrivilegedAction<String>() {
    public String run() {
        try {
            tokenMgr.issueToken(ctx);
        } catch (Exception e) {        
            e.printStackTrace();
        }
        return null;
    }
});
Token token = ctx.getSecurityToken();
String b64Tok = TokenUtil.encodeToken(token);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setReadTimeout(10000);
connection.setRequestProperty("Authorization", AUTH_TYPE_NAME + " " + b64Tok);
connection.connect();
BufferedReader rd = new BufferedReader(new InputStreamReader(
    connection.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = rd.readLine()) != null) {
    sb.append(line);
}
connection.disconnect();
System.out.println(sb.toString());

Destination Domain Configuration:

Note: Here I assumed that, destination domain already have default-keystore configured. Else repeat source domain steps to configure default-keystore and credential store.

11. Repeat step 7 & 8 on destination domain

12. Import source domain certificate into destination domain key store
>keytool -importcert -alias <domainName>-file <domainName>.cer -keystore $DOMAIN_NAME/config/fmwconfig/default-keystore.jks -storepass welome1

13.  Repeat previous Step 9 on destination domain

Now test the integration by accessing source application and make a request to destination.

No comments:

Post a Comment

Provide your thoughts !