Java tutorial
/* * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except * in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.wso2.carbon.identity.application.authz.xacml.pip; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.balana.attr.AttributeValue; import org.wso2.balana.attr.BagAttribute; import org.wso2.balana.attr.StringAttribute; import org.wso2.balana.cond.EvaluationResult; import org.wso2.balana.ctx.EvaluationCtx; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils; import org.wso2.carbon.identity.application.authz.xacml.constants.XACMLAppAuthzConstants; import org.wso2.carbon.identity.base.IdentityConstants; import org.wso2.carbon.identity.entitlement.pip.AbstractPIPAttributeFinder; import java.net.URI; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Properties; import java.util.Set; /** * Provides the attributes from authentication context. The attributes include the following * <ul> * <li><b>http://wso2.org/identity/auth-context-property</b> - Authentication context properties</li> * <li><b>http://wso2.org/identity/auth-context-request-param</b> - Authentication request parameters</li> * <li><b>http://wso2.org/identity/auth-context-request-header</b> - Authentication request headers</li> * <li><b>http://wso2.org/authentication/user-ip</b> - Authenticated user's IP</li> * <li><b>http://wso2.org/authentication/inbound-protocol</b> - Authentication protocol (eg. saml)</li> * </ul> */ public class AuthenticationContextAttributePIP extends AbstractPIPAttributeFinder { private static final String PIP_NAME = "AuthenticationContextAttributePIP"; private static final Set<String> SUPPORTED_ATTRIBUTES; private static final Log log = LogFactory.getLog(AuthenticationContextAttributePIP.class); static { SUPPORTED_ATTRIBUTES = new HashSet<>(); SUPPORTED_ATTRIBUTES.add(XACMLAppAuthzConstants.INBOUND_PROTOCOL_ATTRIBUTE); SUPPORTED_ATTRIBUTES.add(XACMLAppAuthzConstants.CLIENT_IP_ATTRIBUTE); SUPPORTED_ATTRIBUTES.add(XACMLAppAuthzConstants.AUTH_CONTEXT_PROPERTY_CATEGORY); SUPPORTED_ATTRIBUTES.add(XACMLAppAuthzConstants.AUTH_CONTEXT_REQ_PARAM_CATEGORY); SUPPORTED_ATTRIBUTES.add(XACMLAppAuthzConstants.AUTH_CONTEXT_REQ_HEADER_CATEGORY); } /** * Since we override the {@link #getAttributeValues(URI, URI, URI, String, EvaluationCtx)} this won't be called. */ @Override public Set<String> getAttributeValues(String subject, String resource, String action, String environment, String attributeId, String issuer) throws Exception { throw new UnsupportedOperationException("Method unsupported in the context"); } @Override public Set<String> getAttributeValues(URI attributeType, URI attributeId, URI category, String issuer, EvaluationCtx evaluationCtx) throws Exception { EvaluationResult context; String contextId = null; if (StringUtils.isBlank(attributeId.toString())) { log.debug("Empty attribute URI received.."); return Collections.EMPTY_SET; } context = evaluationCtx.getAttribute(new URI(StringAttribute.identifier), new URI(XACMLAppAuthzConstants.AUTH_CTX_ID), issuer, new URI(XACMLAppAuthzConstants.AUTH_CATEGORY)); if (context != null && context.getAttributeValue() != null && context.getAttributeValue().isBag()) { BagAttribute bagAttribute = (BagAttribute) context.getAttributeValue(); if (bagAttribute.size() > 0) { contextId = ((AttributeValue) bagAttribute.iterator().next()).encode(); if (log.isDebugEnabled()) { log.debug(String.format("Finding attributes for the context %1$s", contextId)); } } } if (contextId != null) { AuthenticationContext authCtx = FrameworkUtils.getAuthenticationContextFromCache(contextId); if (authCtx != null) { Set<String> values = new HashSet<>(); switch ((category.toString())) { case XACMLAppAuthzConstants.AUTH_CONTEXT_PROPERTY_CATEGORY: values = getAuthenticationContextProperty(authCtx, attributeType, attributeId, category, issuer, evaluationCtx); break; case XACMLAppAuthzConstants.AUTH_CONTEXT_REQ_PARAM_CATEGORY: values = getAuthenticationRequestParameter(authCtx, attributeType, attributeId, category, issuer, evaluationCtx); break; case XACMLAppAuthzConstants.AUTH_CONTEXT_REQ_HEADER_CATEGORY: values = getAuthenticationRequestHeader(authCtx, attributeType, attributeId, category, issuer, evaluationCtx); break; default: } if (!values.isEmpty()) { if (log.isDebugEnabled()) { String valuesString = StringUtils.join(values, ","); log.debug("Returning " + attributeId + " value as " + valuesString); } return values; } switch (attributeId.toString()) { case XACMLAppAuthzConstants.INBOUND_PROTOCOL_ATTRIBUTE: values.add(authCtx.getRequestType()); break; case XACMLAppAuthzConstants.CLIENT_IP_ATTRIBUTE: Object ipObj = authCtx.getParameter(IdentityConstants.USER_IP); if (ipObj != null) { values.add(ipObj.toString()); } break; default: } if (log.isDebugEnabled()) { String valuesString = StringUtils.join(values, ","); log.debug("Returning " + attributeId + " value as " + valuesString); } return values; } } return Collections.emptySet(); } @Override public void init(Properties properties) throws Exception { } @Override public String getModuleName() { return PIP_NAME; } @Override public Set<String> getSupportedAttributes() { return SUPPORTED_ATTRIBUTES; } protected Set<String> getAuthenticationContextProperty(AuthenticationContext authCtx, URI attributeType, URI attributeId, URI category, String issuer, EvaluationCtx evaluationCtx) { Set<String> values = new HashSet<>(); char separator = getSeparator(attributeId.toString()); String attribute = filterOutCategoryAndSeparator(category.toString(), attributeId.toString(), separator); Object property = authCtx.getProperty(attribute); String attributeValue; if (property != null) { if (property instanceof String) { attributeValue = (String) property; } else { attributeValue = property.toString(); } if (separator != 0) { values.addAll(Arrays.asList(attributeValue.split(String.valueOf(separator)))); } else { values.add(attributeValue); } } return values; } protected Set<String> getAuthenticationRequestParameter(AuthenticationContext authCtx, URI attributeType, URI attributeId, URI category, String issuer, EvaluationCtx evaluationCtx) { Set<String> values = new HashSet<>(); char separator = getSeparator(attributeId.toString()); String queryParam = filterOutCategoryAndSeparator(category.toString(), attributeId.toString(), separator); String[] params = authCtx.getAuthenticationRequest().getRequestQueryParam(queryParam); if (params != null) { if (separator != 0) { for (String param : params) { values.addAll(Arrays.asList(param.split(String.valueOf(separator)))); } } else { Collections.addAll(values, params); } } return values; } protected Set<String> getAuthenticationRequestHeader(AuthenticationContext authCtx, URI attributeType, URI attributeId, URI category, String issuer, EvaluationCtx evaluationCtx) { Set<String> values = new HashSet<>(); char separator = getSeparator(attributeId.toString()); String attributeHeader = filterOutCategoryAndSeparator(category.toString(), attributeId.toString(), separator); String headers = authCtx.getAuthenticationRequest().getRequestHeaders().get(attributeHeader); if (separator != 0) { values.addAll(Arrays.asList(headers.split(String.valueOf(separator)))); } else { values.add(headers); } return values; } protected String filterOutCategoryAndSeparator(String category, String attributeId, char separator) { if (attributeId.startsWith(category)) { //Remove the category and the separator character('/' or ':') following attributeId = attributeId.replaceFirst(category, "").substring(1); } if (separator != 0) { int separatorIdx = attributeId.lastIndexOf(":"); //remove the separator and ':' the following separator attributeId = attributeId.substring(0, separatorIdx); } if (log.isDebugEnabled()) { log.debug("filtered out attribute id is " + attributeId); } return attributeId; } protected char getSeparator(String attributeId) { String[] tokens = attributeId.split(":"); if (tokens.length > 1) { return (char) Integer.parseInt(tokens[tokens.length - 1], 16); } return 0; } }