Search code examples
xacmlwso2-identity-server

WSO2IS - XACML Policy with custom attributes is returning "Couldn't find AttributeDesignator"


I've created the following policy in the WSO2IS:

<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="check-blacklist-users-in-login" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable" Version="1.0">
<Target>
    <AnyOf>
        <AllOf>
            <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">login</AttributeValue>
                <AttributeDesignator AttributeId="urn:custom:company:1.0:operation:login-id"
                                     Category="urn:custom:company:1.0:attribute-category:operation"
                                     DataType="http://www.w3.org/2001/XMLSchema#string"
                                     MustBePresent="true"/>
            </Match>
        </AllOf>
    </AnyOf>
</Target>
<Rule Effect="Permit" RuleId="permit-blacklisted-users-with-step-up">
    <Target>
        <AnyOf>
            <AllOf>
                <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">vip</AttributeValue>
                    <AttributeDesignator AttributeId="urn:custom:company:1.0:user-group:vip-id"
                                         Category="urn:custom:company:1.0:attribute-category:user-group"
                                         DataType="http://www.w3.org/2001/XMLSchema#string"
                                         MustBePresent="true"/>
                </Match>
            </AllOf>
        </AnyOf>
    </Target>
    <Condition>
        <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
            <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
                <AttributeDesignator AttributeId="urn:custom:company:1.0:is-user-in-blacklist:is-user-in-blacklist-id"
                                     Category="urn:custom:company:1.0:attribute-category:is-user-in-blacklist"
                                     DataType="http://www.w3.org/2001/XMLSchema#string"
                                     MustBePresent="true"/>
            </Apply>
            <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">true</AttributeValue>
        </Apply>
    </Condition>
    <ObligationExpressions>
        <ObligationExpression FulfillOn="Permit" ObligationId="extra-email">
            <AttributeAssignmentExpression AttributeId="extra-email">
                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">send-email</AttributeValue>
            </AttributeAssignmentExpression>
        </ObligationExpression>
    </ObligationExpressions>
</Rule>
</Policy>

But when I send the following XACML request:

<Request xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" CombinedDecision="false" ReturnPolicyIdList="false">

<Attributes Category="urn:custom:company:1.0:attribute-category:operation">
    <Attribute AttributeId="urn:custom:company:1.0:operation:login-id" IncludeInResult="false">
        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">login</AttributeValue>
    </Attribute>
</Attributes>

<Attributes Category="urn:custom:company:1.0:attribute-category:user-group">
    <Attribute AttributeId="urn:custom:company:1.0:user-group:vip-id" IncludeInResult="false">
        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">vip</AttributeValue>
    </Attribute>
</Attributes>

<Attributes Category="urn:custom:company:1.0:attribute-category:is-user-in-blacklist">
        <Attribute AttributeId="urn:custom:company:1.0:users:user-id" IncludeInResult="false">
        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">userJon</AttributeValue>
    </Attribute>
</Attributes>
</Request>

I'm always receiving an Indeterminate error regarding AttributeDesignator:

<Response xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17">
<Result>
    <Decision>Indeterminate</Decision>
    <Status>
        <StatusCode Value="urn:oasis:names:tc:xacml:1.0:status:processing-error"/>
        <StatusMessage>Couldn't find AttributeDesignator attribute</StatusMessage>
    </Status>
</Result>
</Response>

I've created a custom PIPAttributeFinder with the following code:

    public class DatabaseAttributeFinder extends LoginDBAttributeFinder {

    private DataSource dataSource;
    private Set<String> supportedAttributes = new HashSet<String>();
    private static Log log = LogFactory.getLog(DatabaseAttributeFinder.class);

    private static final String BLACKLISTED_USER_ID = "urn:custom:company:1.0:is-user-in-blacklist:is-user-in-blacklist-id";

    @Override
    public void init(Properties properties) throws Exception {
        String dataSourceName = (String) properties.get("DataSourceName");

        if(dataSourceName == null || dataSourceName.trim().length() == 0){
            throw new Exception("Data source name can not be null. Please configure it in the entitlement.properties file.");
        }

        dataSource = (DataSource) InitialContext.doLookup(dataSourceName);

        supportedAttributes.add(BLACKLISTED_USER_ID);
    }

... (other code)

And the class LoginDBAttributeFinder, looks like this:

public abstract class LoginDBAttributeFinder implements PIPAttributeFinder {

    protected int tenantId;
    private boolean isAbstractAttributeCachingEnabled = false;
    private PIPAbstractAttributeCache abstractAttributeFinderCache = null;
    private static Log log = LogFactory.getLog(LoginDBAttributeFinder.class);

    public LoginDBAttributeFinder() {
    }

    public abstract Set<String> getAttributeValues(String blacklistUserId,
                                                   String attributeId,
                                                   String issuer) throws Exception;

    @Override
    public Set<String> getAttributeValues(URI attributeType, URI attributeId, URI category, String issuer, EvaluationCtx evaluationCtx) throws Exception {
        String blacklistUserId = null;
        Set attributeValues = null;
        this.tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();

        EvaluationResult blacklistUser = evaluationCtx.getAttribute(new URI("http://www.w3.org/2001/XMLSchema#string"), new URI("urn:custom:company:1.0:users:user-id"), issuer, new URI("urn:custom:company:1.0:attribute-category:is-user-in-blacklist"));

        attributeValues = this.getAttributeValues(blacklistUserId, attributeId.toString(), issuer);

        return attributeValues;

... (other code)

I have successfully registered the jar in WSO2IS (It shows in the admin console) and whenever I go to the TryIt option, and test the specific policy (check-blacklist-users-in-login) it returns Permit, but when I go to the side Menu "Tools" in the WSO2IS' Console, and use the general "TryIt" tool, it returns Indeterminate (Couldn't find AttributeDesignator).

It seems that it can't find a policy and therefore the AttributeDesignator related to the supported attributes of this policy.

I have also try using the REST API (https://WSO2ISIP:4443/api/identity/entitlement/decision/pdp), and also I get: Indeterminate (Couldn't find AttributeDesignator)

Any ideas on how to fix this?


Solution

  • I've found a solution by doing the following steps:

    1. Stop WSO2IS Server
    2. Comment the class of your customAttributeFinder (in my case was DatabaseAttributeFinder) in the file: <WSO2IS_HOME>/repository/conf/identity/entitlement.properties
    3. Start WSO2IS Server
    4. Go to the Admin console and check that there's no customAttributeFinder loaded in the Extension section of Entitlement.
    5. Stop WSO2IS Server
    6. Uncomment your customAttributeFinder in the file of step 2
    7. Start WSO2IS
    8. And by magic everything should work OK.

    There's seem to be a bug in WSO2IS, whenever I modify anything of the Standard Policy Editor, the XACML Engine starts to behave in a very odd way.

    I've seen several StackOverFlow answers where everything is fixed by only restarting the server.

    If you don't want WSO2IS to start going slowly mad, stay away from the XACML Policy Editor.

    If you want proof, check this Jira Issue (specially in the comments section): https://wso2.org/jira/browse/IDENTITY-5447