View Javadoc

    1   /*
    2    * Licensed to the University Corporation for Advanced Internet Development,
    3    * Inc. (UCAID) under one or more contributor license agreements.  See the
    4    * NOTICE file distributed with this work for additional information regarding
    5    * copyright ownership. The UCAID licenses this file to You under the Apache
    6    * License, Version 2.0 (the "License"); you may not use this file except in
    7    * compliance with the License.  You may obtain a copy of the License at
    8    *
    9    *    http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18  package edu.internet2.middleware.shibboleth.idp.profile.saml1;
    19
    20  import org.joda.time.DateTime;
    21  import org.joda.time.chrono.ISOChronology;
    22  import org.opensaml.common.binding.SAMLMessageContext;
    23  import org.opensaml.common.binding.decoding.SAMLMessageDecoder;
    24  import org.opensaml.saml1.binding.decoding.BaseSAML1MessageDecoder;
    25  import org.opensaml.ws.message.MessageContext;
    26  import org.opensaml.ws.message.decoder.MessageDecodingException;
    27  import org.opensaml.ws.transport.http.HTTPInTransport;
    28  import org.opensaml.ws.transport.http.HttpServletRequestAdapter;
    29  import org.opensaml.xml.util.DatatypeHelper;
    30  import org.slf4j.Logger;
    31  import org.slf4j.LoggerFactory;
    32
    33  import edu.internet2.middleware.shibboleth.idp.profile.saml1.ShibbolethSSOProfileHandler.ShibbolethSSORequestContext;
    34
    35  /**
    36   * Shibboleth 1.0 SSO authentication request message decoder.
    37   */
    38  public class ShibbolethSSODecoder extends BaseSAML1MessageDecoder implements SAMLMessageDecoder {
    39
    40      /** Class logger. */
    41      private final Logger log = LoggerFactory.getLogger(ShibbolethSSODecoder.class);
    42
    43      /** Constructor. */
    44      public ShibbolethSSODecoder(){
    45          super();
    46      }
    47
    48      /** {@inheritDoc} */
    49      public String getBindingURI() {
    50          return "urn:mace:shibboleth:1.0:profiles:AuthnRequest";
    51      }
    52
    53      /** {@inheritDoc} */
    54      protected void doDecode(MessageContext messageContext) throws MessageDecodingException {
    55          if (!(messageContext instanceof ShibbolethSSORequestContext)) {
    56              log.warn("Invalid message context type, this decoder only support ShibbolethSSORequestContext");
    57              throw new MessageDecodingException(
    58                      "Invalid message context type, this decoder only support ShibbolethSSORequestContext");
    59          }
    60
    61          if (!(messageContext.getInboundMessageTransport() instanceof HTTPInTransport)) {
    62              log.warn("Invalid inbound message transport type, this decoder only support HTTPInTransport");
    63              throw new MessageDecodingException(
    64                      "Invalid inbound message transport type, this decoder only support HTTPInTransport");
    65          }
    66
    67          ShibbolethSSORequestContext requestContext = (ShibbolethSSORequestContext) messageContext;
    68          HTTPInTransport transport = (HTTPInTransport) messageContext.getInboundMessageTransport();
    69
    70          String providerId = DatatypeHelper.safeTrimOrNullString(transport.getParameterValue("providerId"));
    71          if (providerId == null) {
    72              log.warn("No providerId parameter given in Shibboleth SSO authentication request.");
    73              throw new MessageDecodingException(
    74                      "No providerId parameter given in Shibboleth SSO authentication request.");
    75          }
    76          requestContext.setInboundMessageIssuer(providerId);
    77          requestContext.setPeerEntityId(providerId);
    78
    79          String shire = DatatypeHelper.safeTrimOrNullString(transport.getParameterValue("shire"));
    80          if (shire == null) {
    81              log.warn("No shire parameter given in Shibboleth SSO authentication request.");
    82              throw new MessageDecodingException("No shire parameter given in Shibboleth SSO authentication request.");
    83          }
    84          requestContext.setSpAssertionConsumerService(shire);
    85
    86          String target = DatatypeHelper.safeTrimOrNullString(transport.getParameterValue("target"));
    87          if (target == null) {
    88              log.warn("No target parameter given in Shibboleth SSO authentication request.");
    89              throw new MessageDecodingException("No target parameter given in Shibboleth SSO authentication request.");
    90          }
    91          requestContext.setRelayState(target);
    92
    93          String timeStr = DatatypeHelper.safeTrimOrNullString(transport.getParameterValue("time"));
    94          if (timeStr != null) {
    95              long time = Long.parseLong(timeStr) * 1000;
    96              requestContext.setInboundSAMLMessageIssueInstant(new DateTime(time, ISOChronology.getInstanceUTC()));
    97
    98              // If a timestamp is provided, construct a pseudo message ID by combining the timestamp
    99              // and a client-specific ID (the Java session ID).
    100             String sessionID = ((HttpServletRequestAdapter) transport).getWrappedRequest().getRequestedSessionId();
    101             if (sessionID != null) {
    102                 requestContext.setInboundSAMLMessageId(sessionID + '!' + timeStr);
    103             }
    104         }
    105
    106         populateRelyingPartyMetadata(requestContext);
    107     }
    108
    109     /** {@inheritDoc} */
    110     protected boolean isIntendedDestinationEndpointURIRequired(SAMLMessageContext samlMsgCtx) {
    111         return false;
    112     }
    113
    114     /** {@inheritDoc} */
    115     protected String getIntendedDestinationEndpointURI(SAMLMessageContext samlMsgCtx) throws MessageDecodingException {
    116         // Not relevant in this binding/profile, there is neither SAML message
    117         // nor binding parameter with this information
    118         return null;
    119     }
    120
    121 }