All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.apache.wss4j.policy.stax.assertionStates.IssuedTokenAssertionState Maven / Gradle / Ivy
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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.apache.wss4j.policy.stax.assertionStates;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.saml.SamlAssertionWrapper;
import org.apache.wss4j.common.WSSPolicyException;
import org.apache.wss4j.policy.model.AbstractSecurityAssertion;
import org.apache.wss4j.policy.model.AbstractToken;
import org.apache.wss4j.policy.model.IssuedToken;
import org.apache.wss4j.policy.stax.PolicyAsserter;
import org.apache.wss4j.stax.ext.WSSConstants;
import org.apache.wss4j.stax.securityEvent.KerberosTokenSecurityEvent;
import org.apache.wss4j.stax.securityEvent.SamlTokenSecurityEvent;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.stax.securityEvent.SecurityEventConstants;
import org.apache.xml.security.stax.securityEvent.TokenSecurityEvent;
import org.apache.xml.security.stax.securityToken.SecurityToken;
import org.apache.wss4j.stax.securityEvent.IssuedTokenSecurityEvent;
import org.apache.wss4j.stax.securityEvent.WSSecurityEventConstants;
import org.opensaml.saml.common.SAMLVersion;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import java.net.URI;
import java.security.Key;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;
/**
* WSP1.3, 5.4.2 IssuedToken Assertion
*/
public class IssuedTokenAssertionState extends TokenAssertionState {
private static final String DEFAULT_CLAIMS_NAMESPACE =
"http://schemas.xmlsoap.org/ws/2005/05/identity";
public IssuedTokenAssertionState(AbstractSecurityAssertion assertion, boolean asserted,
PolicyAsserter policyAsserter, boolean initiator) {
super(assertion, asserted, policyAsserter, initiator);
}
@Override
public SecurityEventConstants.Event[] getSecurityEventType() {
return new SecurityEventConstants.Event[]{
WSSecurityEventConstants.KERBEROS_TOKEN,
WSSecurityEventConstants.REL_TOKEN,
WSSecurityEventConstants.SAML_TOKEN,
WSSecurityEventConstants.SECURITY_CONTEXT_TOKEN,
};
}
@Override
public boolean assertToken(TokenSecurityEvent extends SecurityToken> tokenSecurityEvent,
AbstractToken abstractToken) throws WSSPolicyException {
if (!(tokenSecurityEvent instanceof IssuedTokenSecurityEvent)) {
throw new WSSPolicyException("Expected a IssuedTokenSecurityEvent but got " + tokenSecurityEvent.getClass().getName());
}
IssuedToken issuedToken = (IssuedToken) abstractToken;
IssuedTokenSecurityEvent extends SecurityToken> issuedTokenSecurityEvent
= (IssuedTokenSecurityEvent extends SecurityToken>) tokenSecurityEvent;
try {
if (issuedToken.getIssuerName() != null
&& !issuedToken.getIssuerName().equals(issuedTokenSecurityEvent.getIssuerName())) {
setErrorMessage("IssuerName in Policy (" + issuedToken.getIssuerName()
+ ") didn't match with the one in the IssuedToken (" + issuedTokenSecurityEvent.getIssuerName() + ")");
getPolicyAsserter().unassertPolicy(getAssertion(), getErrorMessage());
return false;
}
if (issuedToken.getRequestSecurityTokenTemplate() != null) {
if (issuedTokenSecurityEvent instanceof SamlTokenSecurityEvent) {
SamlTokenSecurityEvent samlTokenSecurityEvent = (SamlTokenSecurityEvent) issuedTokenSecurityEvent;
String errorMsg = checkIssuedTokenTemplate(issuedToken.getRequestSecurityTokenTemplate(), samlTokenSecurityEvent);
if (errorMsg != null) {
setErrorMessage(errorMsg);
getPolicyAsserter().unassertPolicy(getAssertion(), getErrorMessage());
return false;
}
} else if (issuedTokenSecurityEvent instanceof KerberosTokenSecurityEvent) {
KerberosTokenSecurityEvent kerberosTokenSecurityEvent = (KerberosTokenSecurityEvent) issuedTokenSecurityEvent;
String errorMsg = checkIssuedTokenTemplate(issuedToken.getRequestSecurityTokenTemplate(), kerberosTokenSecurityEvent);
if (errorMsg != null) {
setErrorMessage(errorMsg);
getPolicyAsserter().unassertPolicy(getAssertion(), getErrorMessage());
return false;
}
}
}
Element claims = issuedToken.getClaims();
if (claims != null && issuedTokenSecurityEvent instanceof SamlTokenSecurityEvent) {
String errorMsg =
validateClaims((Element) claims, (SamlTokenSecurityEvent)issuedTokenSecurityEvent);
if (errorMsg != null) {
setErrorMessage(errorMsg);
getPolicyAsserter().unassertPolicy(getAssertion(), getErrorMessage());
return false;
}
}
} catch (XMLSecurityException e) {
getPolicyAsserter().unassertPolicy(getAssertion(), getErrorMessage());
throw new WSSPolicyException(e.getMessage(), e);
}
//always return true to prevent false alarm in case additional tokens with the same usage
//appears in the message but do not fulfill the policy and are also not needed to fulfil the policy.
getPolicyAsserter().assertPolicy(getAssertion());
return true;
}
/**
* Check the issued token template against the received assertion
*/
protected String checkIssuedTokenTemplate(Element template, SamlTokenSecurityEvent samlTokenSecurityEvent) throws XMLSecurityException {
Node child = template.getFirstChild();
while (child != null) {
if (child.getNodeType() != Node.ELEMENT_NODE) {
child = child.getNextSibling();
continue;
}
if ("TokenType".equals(child.getLocalName())) {
String content = child.getTextContent();
final SAMLVersion samlVersion = samlTokenSecurityEvent.getSamlAssertionWrapper().getSamlVersion();
if (WSSConstants.NS_SAML11_TOKEN_PROFILE_TYPE.equals(content)
&& samlVersion != SAMLVersion.VERSION_11) {
return "Policy enforces SAML V1.1 token but got " + samlVersion.toString();
} else if (WSSConstants.NS_SAML20_TOKEN_PROFILE_TYPE.equals(content)
&& samlVersion != SAMLVersion.VERSION_20) {
return "Policy enforces SAML V2.0 token but got " + samlVersion.toString();
}
} else if ("KeyType".equals(child.getLocalName())) {
String content = child.getTextContent();
if (content.endsWith("SymmetricKey")) {
Map subjectKeys = samlTokenSecurityEvent.getSecurityToken().getSecretKey();
if (subjectKeys.isEmpty()) {
return "Policy enforces SAML token with a symmetric key";
}
} else if (content.endsWith("PublicKey")) {
PublicKey publicKey = samlTokenSecurityEvent.getSecurityToken().getPublicKey();
X509Certificate[] x509Certificate = samlTokenSecurityEvent.getSecurityToken().getX509Certificates();
if (publicKey == null && x509Certificate == null) {
return "Policy enforces SAML token with an asymmetric key";
}
}
} else if ("Claims".equals(child.getLocalName())) {
String errorMsg = validateClaims((Element) child, samlTokenSecurityEvent);
if (errorMsg != null) {
return errorMsg;
}
}
child = child.getNextSibling();
}
return null;
}
/**
* Check the issued token template against the received BinarySecurityToken
*/
private String checkIssuedTokenTemplate(Element template, KerberosTokenSecurityEvent kerberosTokenSecurityEvent) {
Node child = template.getFirstChild();
while (child != null) {
if (child.getNodeType() != Node.ELEMENT_NODE) {
child = child.getNextSibling();
continue;
}
if ("TokenType".equals(child.getLocalName())) {
String content = child.getTextContent();
String valueType = kerberosTokenSecurityEvent.getKerberosTokenValueType();
if (!content.equals(valueType)) {
return "Policy enforces Kerberos token of type " + content + " but got " + valueType;
}
}
child = child.getNextSibling();
}
return null;
}
//todo I think the best is if we allow to set custom AssertionStates object on the policy-engine for
//custom validation -> task for WSS4j V2.1 ?
protected String validateClaims(Element claimsPolicy, SamlTokenSecurityEvent samlTokenSecurityEvent) throws WSSecurityException {
String dialect = claimsPolicy.getAttributeNS(null, "Dialect");
if (!DEFAULT_CLAIMS_NAMESPACE.equals(dialect)) {
return null;
}
Node child = claimsPolicy.getFirstChild();
while (child != null) {
if (child.getNodeType() != Node.ELEMENT_NODE) {
child = child.getNextSibling();
continue;
}
if ("ClaimType".equals(child.getLocalName())) {
Element claimType = (Element) child;
String claimTypeUri = claimType.getAttributeNS(null, "Uri");
String claimTypeOptional = claimType.getAttributeNS(null, "Optional");
if ("".equals(claimTypeOptional) || !Boolean.parseBoolean(claimTypeOptional)) {
String errorMsg = findClaimInAssertion(samlTokenSecurityEvent.getSamlAssertionWrapper(), URI.create(claimTypeUri));
if (errorMsg != null) {
return errorMsg;
}
}
}
child = child.getNextSibling();
}
return null;
}
protected String findClaimInAssertion(SamlAssertionWrapper samlAssertionWrapper, URI claimURI) {
if (samlAssertionWrapper.getSaml1() != null) {
return findClaimInAssertion(samlAssertionWrapper.getSaml1(), claimURI);
} else if (samlAssertionWrapper.getSaml2() != null) {
return findClaimInAssertion(samlAssertionWrapper.getSaml2(), claimURI);
}
return "Unsupported SAML version";
}
protected String findClaimInAssertion(org.opensaml.saml.saml2.core.Assertion assertion, URI claimURI) {
List attributeStatements =
assertion.getAttributeStatements();
if (attributeStatements == null || attributeStatements.isEmpty()) {
return "Attribute " + claimURI + " not found in the SAMLAssertion";
}
for (org.opensaml.saml.saml2.core.AttributeStatement statement : attributeStatements) {
List attributes = statement.getAttributes();
for (org.opensaml.saml.saml2.core.Attribute attribute : attributes) {
if (attribute.getName().equals(claimURI.toString())
&& attribute.getAttributeValues() != null && !attribute.getAttributeValues().isEmpty()) {
return null;
}
}
}
return "Attribute " + claimURI + " not found in the SAMLAssertion";
}
protected String findClaimInAssertion(org.opensaml.saml.saml1.core.Assertion assertion, URI claimURI) {
List attributeStatements =
assertion.getAttributeStatements();
if (attributeStatements == null || attributeStatements.isEmpty()) {
return "Attribute " + claimURI + " not found in the SAMLAssertion";
}
for (org.opensaml.saml.saml1.core.AttributeStatement statement : attributeStatements) {
List attributes = statement.getAttributes();
for (org.opensaml.saml.saml1.core.Attribute attribute : attributes) {
URI attributeNamespace = URI.create(attribute.getAttributeNamespace());
String desiredRole = attributeNamespace.relativize(claimURI).toString();
if (attribute.getAttributeName().equals(desiredRole)
&& attribute.getAttributeValues() != null && !attribute.getAttributeValues().isEmpty()) {
return null;
}
}
}
return "Attribute " + claimURI + " not found in the SAMLAssertion";
}
}