View Javadoc
1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.wss4j.policy.stax.assertionStates;
20  
21  import javax.xml.namespace.QName;
22  
23  import org.apache.wss4j.common.saml.SamlAssertionWrapper;
24  import org.apache.wss4j.common.WSSPolicyException;
25  import org.apache.wss4j.policy.SPConstants;
26  import org.apache.wss4j.policy.model.AbstractSecurityAssertion;
27  import org.apache.wss4j.policy.model.AbstractToken;
28  import org.apache.wss4j.policy.model.SamlToken;
29  import org.apache.wss4j.policy.stax.PolicyAsserter;
30  import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
31  import org.apache.xml.security.exceptions.XMLSecurityException;
32  import org.opensaml.saml.common.SAMLVersion;
33  import org.apache.wss4j.stax.securityEvent.SamlTokenSecurityEvent;
34  import org.apache.wss4j.stax.securityEvent.WSSecurityEventConstants;
35  import org.apache.xml.security.stax.securityEvent.SecurityEventConstants;
36  import org.apache.xml.security.stax.securityEvent.TokenSecurityEvent;
37  import org.apache.xml.security.stax.securityToken.SecurityToken;
38  import org.apache.xml.security.stax.securityToken.SecurityTokenConstants.KeyIdentifier;
39  
40  /**
41   * WSP1.3, 5.4.8 SamlToken Assertion
42   */
43  
44  public class SamlTokenAssertionState extends TokenAssertionState {
45  
46      public SamlTokenAssertionState(AbstractSecurityAssertion assertion, boolean asserted,
47                                     PolicyAsserter policyAsserter, boolean initiator) {
48          super(assertion, asserted, policyAsserter, initiator);
49  
50          if (asserted) {
51              SamlToken token = (SamlToken) getAssertion();
52              String namespace = token.getName().getNamespaceURI();
53              if (token.isRequireKeyIdentifierReference()) {
54                  getPolicyAsserter().assertPolicy(new QName(namespace, SPConstants.REQUIRE_KEY_IDENTIFIER_REFERENCE));
55              }
56              if (token.getSamlTokenType() != null) {
57                  getPolicyAsserter().assertPolicy(new QName(namespace, token.getSamlTokenType().name()));
58              }
59          }
60      }
61  
62      @Override
63      public SecurityEventConstants.Event[] getSecurityEventType() {
64          return new SecurityEventConstants.Event[]{
65                  WSSecurityEventConstants.SAML_TOKEN
66          };
67      }
68  
69      @Override
70      public boolean assertToken(TokenSecurityEvent<? extends SecurityToken> tokenSecurityEvent,
71                                 AbstractToken abstractToken) throws WSSPolicyException, XMLSecurityException {
72          if (!(tokenSecurityEvent instanceof SamlTokenSecurityEvent)) {
73              throw new WSSPolicyException("Expected a SamlTokenSecurityEvent but got " + tokenSecurityEvent.getClass().getName());
74          }
75          SamlTokenSecurityEvent samlTokenSecurityEvent = (SamlTokenSecurityEvent) tokenSecurityEvent;
76          SamlToken samlToken = (SamlToken) abstractToken;
77  
78          if (samlToken.getIssuerName() != null && !samlToken.getIssuerName().equals(samlTokenSecurityEvent.getIssuerName())) {
79              setErrorMessage("IssuerName in Policy (" + samlToken.getIssuerName() + ") didn't match with the one in the SamlToken ("
80                  + samlTokenSecurityEvent.getIssuerName() + ")");
81              getPolicyAsserter().unassertPolicy(getAssertion(), getErrorMessage());
82              return false;
83          }
84  
85          String namespace = getAssertion().getName().getNamespaceURI();
86          if (samlToken.isRequireKeyIdentifierReference()) {
87              KeyIdentifier keyIdentifier = samlTokenSecurityEvent.getSecurityToken().getKeyIdentifier();
88              if (!WSSecurityTokenConstants.KeyIdentifier_X509KeyIdentifier.equals(keyIdentifier)) {
89                  setErrorMessage("Policy enforces KeyIdentifierReference but we got "
90                      + samlTokenSecurityEvent.getSecurityToken().getTokenType());
91                  getPolicyAsserter().unassertPolicy(new QName(namespace, SPConstants.REQUIRE_KEY_IDENTIFIER_REFERENCE),
92                                                   getErrorMessage());
93                  return false;
94              } else {
95                  getPolicyAsserter().assertPolicy(new QName(namespace, SPConstants.REQUIRE_KEY_IDENTIFIER_REFERENCE));
96              }
97          }
98          if (samlToken.getSamlTokenType() != null) {
99              final SamlAssertionWrapper samlAssertionWrapper = samlTokenSecurityEvent.getSamlAssertionWrapper();
100             switch (samlToken.getSamlTokenType()) {
101                 case WssSamlV11Token10:
102                     if (samlAssertionWrapper.getSamlVersion() != SAMLVersion.VERSION_11) {
103                         setErrorMessage("Policy enforces SamlVersion11Profile10 but we got " + samlAssertionWrapper.getSamlVersion());
104                         getPolicyAsserter().unassertPolicy(new QName(namespace, samlToken.getSamlTokenType().name()),
105                                                          getErrorMessage());
106                         return false;
107                     }
108                     getPolicyAsserter().assertPolicy(new QName(namespace, samlToken.getSamlTokenType().name()));
109                     break;
110                 case WssSamlV11Token11:
111                     if (samlAssertionWrapper.getSamlVersion() != SAMLVersion.VERSION_11) {
112                         setErrorMessage("Policy enforces SamlVersion11Profile11 but we got " + samlAssertionWrapper.getSamlVersion());
113                         getPolicyAsserter().unassertPolicy(new QName(namespace, samlToken.getSamlTokenType().name()),
114                                                            getErrorMessage());
115                         return false;
116                     }
117                     getPolicyAsserter().assertPolicy(new QName(namespace, samlToken.getSamlTokenType().name()));
118                     break;
119                 case WssSamlV20Token11:
120                     if (samlAssertionWrapper.getSamlVersion() != SAMLVersion.VERSION_20) {
121                         setErrorMessage("Policy enforces SamlVersion20Profile11 but we got " + samlAssertionWrapper.getSamlVersion());
122                         getPolicyAsserter().unassertPolicy(new QName(namespace, samlToken.getSamlTokenType().name()),
123                                                            getErrorMessage());
124                         return false;
125                     }
126                     getPolicyAsserter().assertPolicy(new QName(namespace, samlToken.getSamlTokenType().name()));
127                     break;
128                 case WssSamlV10Token10:
129                 case WssSamlV10Token11:
130                     setErrorMessage("Unsupported token type: " + samlToken.getSamlTokenType());
131                     getPolicyAsserter().unassertPolicy(new QName(namespace, samlToken.getSamlTokenType().name()),
132                                                        getErrorMessage());
133                     return false;
134             }
135         }
136         //always return true to prevent false alarm in case additional tokens with the same usage
137         //appears in the message but do not fulfill the policy and are also not needed to fulfil the policy.
138         getPolicyAsserter().assertPolicy(getAssertion());
139         return true;
140     }
141 }