12 December 2018

Custom Claim Handler in Fediz Plugin

Apache Fediz plugin provides now a support for custom claim processing since version 1.4.5. This allows fine grained claim control on application side, which is very useful if you are not in control of the IDP/STS claim creation itself. Or if you want to do some local claim value mapping that is very application specific.

In this blog post, I will show you how to leverage this new Fediz feature.

If you want to provide your own Claim Parser you need to implement the following interface
package org.apache.cxf.fediz.core.processor;

import java.util.List;
import org.apache.cxf.fediz.core.Claim;

public interface ClaimsProcessor {

    /**
     * This operation can be used to transform, filter or trigger other actions
     * based on the input claims. The response can be the same list of claims as
     * from the input parameter, a subset of it or a renamed or extended list of
     * claims.
     * 
     * @param claims Claims to be processed
     * @return List of processed claims
     */
    List<claim> processClaims(List<claim> claims);

}
Here is a sample implementation of this interface showing you how easy it is to change any value of a given claim. Or even adding additional claims that have not been part of the original SAML token.
import java.util.ArrayList;
package org.apache.cxf.fediz.common;

import java.util.List;
import org.apache.cxf.fediz.core.Claim;
import org.apache.cxf.fediz.core.ClaimTypes;
import org.apache.cxf.fediz.core.processor.ClaimsProcessor;

/**
 * Changes claim type and claim value
 */
public class ClaimMutateProcessor implements ClaimsProcessor {

    @Override
    public List<claim> processClaims(List<claim> claims) {
        List<claim> newClaimList = new ArrayList<>();

        for (Claim c : claims) {
            // Check if one claim is of type privatepersonalidentifier 
            if (ClaimTypes.PRIVATE_PERSONAL_IDENTIFIER.equals(c.getClaimType())) {
                //Create new claim of type givenname
                Claim lowerClaim = new Claim();
                lowerClaim.setClaimType(ClaimTypes.FIRSTNAME);
                // Copy value from source claim to new claim as lowercase text 
                lowerClaim.setValue(c.getValue().toString().toLowerCase());

                //Create second claim of type surname
                Claim upperClaim = new Claim();
                upperClaim.setClaimType(ClaimTypes.LASTNAME);
                // Copy value from source claim to new claim as UPPERCASE text
                upperClaim.setValue(c.getValue().toString().toUpperCase());

                // Add both claims to response
                newClaimList.add(lowerClaim);
                newClaimList.add(upperClaim);
            }
        }

        return newClaimList;
    }
}
You need to package your custom implementation as a jar file and add it together with the other Apache Fediz Plugin libraries to your application container.

Next you need to enable the claim processor by adding it to your Fediz configuration:
<?xml version="1.0" encoding="UTF-8"?>
<FedizConfig>
    <contextConfig name="/fedizhelloworld">
        <audienceUris>
            <audienceItem>urn:org:apache:cxf:fediz:fedizhelloworld</audienceItem>
        </audienceUris>
        <certificateStores>
            <trustManager>
                <keyStore file="test-classes/clienttrust.jks"
                          password="storepass" type="JKS" />
            </trustManager>
        </certificateStores>
        <trustedIssuers>
            <issuer certificateValidation="PeerTrust" />
        </trustedIssuers>
        <maximumClockSkew>1000</maximumClockSkew>
        <protocol xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:type="federationProtocolType" version="1.0.0">
            <realm>urn:org:apache:cxf:fediz:fedizhelloworld</realm>
            <issuer>https://localhost:${idp.https.port}/fediz-idp/federation</issuer>
            <roleDelimiter>,</roleDelimiter>
            <roleURI>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role</roleURI>
            <freshness>10</freshness>
            <homeRealm type="String">urn:org:apache:cxf:fediz:idp:realm-A</homeRealm>
            <claimTypesRequested>
                <claimType type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role" optional="false" />
                <claimType type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname" optional="true" />
                <claimType type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname" optional="true" />
                <claimType type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier" optional="true" />
            </claimTypesRequested>
        </protocol>
        <logoutURL>/secure/logout</logoutURL>
        <logoutRedirectTo>/index.html</logoutRedirectTo>
        <claimsProcessor type="Class">org.apache.cxf.fediz.common.ClaimMutateProcessor</claimsProcessor>
        <!-- you can have one or more claimsProcessor elements added here -->
</contextConfig>
</FedizConfig>
That's it. Next time you invoke your service, you will see that the user has firstname and lastname claims set instead of a privatepersonalidentifier.

No comments:

Post a Comment