/** {@inheritDoc} */
  protected void processAttribute(XMLObject xmlObject, Attr attribute)
      throws UnmarshallingException {

    AttributeDesignatorType attributeDesignatorType = (AttributeDesignatorType) xmlObject;

    if (attribute.getLocalName().equals(AttributeDesignatorType.ATTRIBUTE_ID_ATTRIB_NAME)) {
      attributeDesignatorType.setAttribtueId(
          DatatypeHelper.safeTrimOrNullString(attribute.getValue()));
    } else if (attribute.getLocalName().equals(AttributeDesignatorType.DATA_TYPE_ATTRIB_NAME)) {
      attributeDesignatorType.setDataType(
          DatatypeHelper.safeTrimOrNullString(attribute.getValue()));
    } else if (attribute.getLocalName().equals(AttributeDesignatorType.ISSUER_ATTRIB_NAME)) {
      attributeDesignatorType.setIssuer(DatatypeHelper.safeTrimOrNullString(attribute.getValue()));
    } else if (attribute
        .getLocalName()
        .equals(AttributeDesignatorType.MUST_BE_PRESENT_ATTRIB_NAME)) {
      if (attribute.getValue().equals("True") || attribute.getValue().equals("true")) {
        attributeDesignatorType.setMustBePresentXSBoolean(XSBooleanValue.valueOf("1"));
      } else {
        attributeDesignatorType.setMustBePresentXSBoolean(XSBooleanValue.valueOf("0"));
      }
    } else {
      super.processAttribute(xmlObject, attribute);
    }
  }
  /**
   * Checks that all the attributes have a unique Name/NameFormat pair.
   *
   * @param query the attribute query to validate
   * @throws ValidationException thrown if more than on Name/NameFormat pair is found in the list of
   *     attributes in this query
   */
  protected void validateUniqueAttributeIdentifiers(AttributeQuery query)
      throws ValidationException {
    List<Attribute> attributes = query.getAttributes();

    HashSet<Pair<String, String>> encounteredNames = new HashSet<Pair<String, String>>();
    String attributeName;
    String attributeNameFormat;
    for (Attribute attribute : attributes) {
      attributeName = attribute.getName();
      attributeNameFormat = attribute.getNameFormat();
      if (DatatypeHelper.isEmpty(attributeNameFormat)) {
        // SAML 2 core, sec. 2.7.3.1, if no format is specified,
        // unspecified is in effect. This avoids bug in processing null value.
        attributeNameFormat = Attribute.UNSPECIFIED;
      }

      Pair<String, String> pair = new Pair<String, String>(attributeName, attributeNameFormat);
      if (encounteredNames.contains(pair)) {
        throw new ValidationException(
            "Attribute query contains more than one attribute with the same Name and NameFormat");
      } else {
        encounteredNames.add(pair);
      }
    }
  }
  /**
   * Validates that the authentication was successfully performed by the login handler. An
   * authentication is considered successful if no error is bound to the request attribute {@link
   * LoginHandler#AUTHENTICATION_ERROR_KEY} and there is a value for at least one of the following
   * request attributes: {@link LoginHandler#SUBJECT_KEY}, {@link LoginHandler#PRINCIPAL_KEY}, or
   * {@link LoginHandler#PRINCIPAL_NAME_KEY}.
   *
   * @param loginContext current login context
   * @param httpRequest current HTTP request
   * @param authenticationMethod the authentication method used to authenticate the user
   * @throws AuthenticationException thrown if the authentication was not successful
   */
  protected void validateSuccessfulAuthentication(
      LoginContext loginContext, HttpServletRequest httpRequest, String authenticationMethod)
      throws AuthenticationException {
    LOG.debug("Validating authentication was performed successfully");

    if (authenticationMethod == null) {
      LOG.error("No authentication method reported by login handler.");
      throw new AuthenticationException("No authentication method reported by login handler.");
    }

    String errorMessage =
        DatatypeHelper.safeTrimOrNullString(
            (String) httpRequest.getAttribute(LoginHandler.AUTHENTICATION_ERROR_KEY));
    if (errorMessage != null) {
      LOG.debug(
          "Error returned from login handler for authentication method {}:\n{}",
          loginContext.getAttemptedAuthnMethod(),
          errorMessage);
      loginContext.setAuthenticationFailure(new AuthenticationException(errorMessage));
      loginContext.setPrincipalAuthenticated(false);
      return;
    }

    AuthenticationException authnException =
        (AuthenticationException)
            httpRequest.getAttribute(LoginHandler.AUTHENTICATION_EXCEPTION_KEY);
    if (authnException != null) {
      LOG.debug(
          "Exception returned from login handler for authentication method {}:\n{}",
          loginContext.getAttemptedAuthnMethod(),
          authnException);
      loginContext.setAuthenticationFailure(authnException);
      loginContext.setPrincipalAuthenticated(false);
      return;
    }

    Subject subject = (Subject) httpRequest.getAttribute(LoginHandler.SUBJECT_KEY);
    Principal principal = (Principal) httpRequest.getAttribute(LoginHandler.PRINCIPAL_KEY);
    String principalName =
        DatatypeHelper.safeTrimOrNullString(
            (String) httpRequest.getAttribute(LoginHandler.PRINCIPAL_NAME_KEY));

    if (subject == null && principal == null && principalName == null) {
      LOG.error("No user identified by login handler.");
      throw new AuthenticationException("No user identified by login handler.");
    }
  }
  /** {@inheritDoc} */
  protected void marshallAttributes(XMLObject xmlObject, Element domElement)
      throws MarshallingException {
    SubjectMatchType matchType = (SubjectMatchType) xmlObject;

    if (!DatatypeHelper.isEmpty(matchType.getMatchId())) {
      domElement.setAttribute(SubjectMatchType.MATCH_ID_ATTRIB_NAME, matchType.getMatchId());
    }
  }
예제 #5
0
 /** {@inheritDoc} */
 protected void unmarshallTextContent(XMLObject xmlObject, Text content)
     throws UnmarshallingException {
   String textContent = DatatypeHelper.safeTrimOrNullString(content.getWholeText());
   if (textContent != null) {
     XSQName qname = (XSQName) xmlObject;
     qname.setValue(XMLHelper.constructQName(textContent, XMLHelper.getElementAncestor(content)));
   }
 }
  /**
   * Extracts the authentication methods requested within the request.
   *
   * @param request the authentication request
   * @return requested authentication methods, or an empty list if no preference
   */
  protected List<String> extractRequestedAuthenticationMethods(AuthnRequest request) {
    LazyList<String> requestedMethods = new LazyList<String>();

    RequestedAuthnContext authnContext = request.getRequestedAuthnContext();
    if (authnContext == null) {
      return requestedMethods;
    }

    // For the immediate future, we only support the "exact" comparator.
    AuthnContextComparisonTypeEnumeration comparator = authnContext.getComparison();
    if (comparator != null && comparator != AuthnContextComparisonTypeEnumeration.EXACT) {
      Logger log = LoggerFactory.getLogger(Saml2LoginContext.class);
      log.warn(
          "Unsupported comparision operator ( "
              + comparator
              + ") in RequestedAuthnContext. Only exact comparisions are supported.");
      return requestedMethods;
    }

    // build a list of all requested authn classes and declrefs
    List<AuthnContextClassRef> authnClasses = authnContext.getAuthnContextClassRefs();
    if (authnClasses != null) {
      for (AuthnContextClassRef classRef : authnClasses) {
        if (classRef != null && !DatatypeHelper.isEmpty(classRef.getAuthnContextClassRef())) {
          requestedMethods.add(classRef.getAuthnContextClassRef());
        }
      }
    }

    List<AuthnContextDeclRef> authnDeclRefs = authnContext.getAuthnContextDeclRefs();
    if (authnDeclRefs != null) {
      for (AuthnContextDeclRef declRef : authnDeclRefs) {
        if (declRef != null && !DatatypeHelper.isEmpty(declRef.getAuthnContextDeclRef())) {
          requestedMethods.add(declRef.getAuthnContextDeclRef());
        }
      }
    }

    if (requestedMethods.contains(AuthnContext.UNSPECIFIED_AUTHN_CTX)) {
      requestedMethods.clear();
    }

    return requestedMethods;
  }
 /**
  * Constructor.
  *
  * @param extensionSchemas classpath location of metadata extension schemas, may be null
  */
 public SchemaValidationFilter(String[] extensionSchemas) {
   if (extensionSchemas != null) {
     for (String extension : extensionSchemas) {
       extension = DatatypeHelper.safeTrimOrNullString(extension);
       if (extension != null) {
         SAMLSchemaBuilder.addExtensionSchema(extension);
       }
     }
   }
 }
  /**
   * Gets the list of request paths the profile handler handles.
   *
   * @param config profile handler configuration element
   * @return list of request paths the profile handler handles
   */
  protected List<String> getRequestPaths(Element config) {
    ArrayList<String> requestPaths = new ArrayList<String>();
    List<Element> requestPathElems = XMLHelper.getChildElementsByTagName(config, "RequestPath");
    if (requestPathElems != null) {
      for (Element requestPathElem : requestPathElems) {
        requestPaths.add(DatatypeHelper.safeTrimOrNullString(requestPathElem.getTextContent()));
      }
    }

    return requestPaths;
  }
  /** {@inheritDoc} */
  protected BaseAttribute<String> doResolve(ShibbolethResolutionContext resolutionContext) {
    BasicAttribute<String> attribute = new BasicAttribute<String>();
    attribute.setId(getId());

    String authnMethod =
        resolutionContext.getAttributeRequestContext().getPrincipalAuthenticationMethod();
    if (!DatatypeHelper.isEmpty(authnMethod)) {
      attribute.getValues().add(authnMethod);
    }

    return attribute;
  }
  /** {@inheritDoc} */
  public void init(ServletConfig config) throws ServletException {
    super.init(config);

    String retain =
        DatatypeHelper.safeTrimOrNullString(config.getInitParameter(RETAIN_PRIVATE_CREDENTIALS));
    if (retain != null) {
      retainSubjectsPrivateCredentials = Boolean.parseBoolean(retain);
    } else {
      retainSubjectsPrivateCredentials = false;
    }

    retain =
        DatatypeHelper.safeTrimOrNullString(config.getInitParameter(RETAIN_PUBLIC_CREDENTIALS));
    if (retain != null) {
      retainSubjectsPublicCredentials = Boolean.parseBoolean(retain);
    } else {
      retainSubjectsPublicCredentials = false;
    }
    context = config.getServletContext();
    handlerManager = HttpServletHelper.getProfileHandlerManager(context);
    sessionManager = HttpServletHelper.getSessionManager(context);
    storageService =
        (StorageService<String, LoginContextEntry>) HttpServletHelper.getStorageService(context);
  }
예제 #11
0
  /** {@inheritDoc} */
  public void init(ServletConfig config) throws ServletException {
    super.init(config);

    allowedIPs = new LazyList<IPRange>();

    String cidrBlocks = DatatypeHelper.safeTrimOrNullString(config.getInitParameter(IP_PARAM_NAME));
    if (cidrBlocks != null) {
      for (String cidrBlock : cidrBlocks.split(" ")) {
        allowedIPs.add(IPRange.parseCIDRBlock(cidrBlock));
      }
    }

    dateFormat = ISODateTimeFormat.dateTimeNoMillis();
    startTime = new DateTime(ISOChronology.getInstanceUTC());
    attributeResolver = HttpServletHelper.getAttributeResolver(config.getServletContext());
    rpConfigManager =
        HttpServletHelper.getRelyingPartyConfirmationManager(config.getServletContext());
  }
  /**
   * Gets the subject from the request coming back from the login handler.
   *
   * @param httpRequest request coming back from the login handler
   * @return the {@link Subject} created from the request
   * @throws AuthenticationException thrown if no subject can be retrieved from the request
   */
  protected Subject getLoginHandlerSubject(HttpServletRequest httpRequest)
      throws AuthenticationException {
    Subject subject = (Subject) httpRequest.getAttribute(LoginHandler.SUBJECT_KEY);
    Principal principal = (Principal) httpRequest.getAttribute(LoginHandler.PRINCIPAL_KEY);
    String principalName =
        DatatypeHelper.safeTrimOrNullString(
            (String) httpRequest.getAttribute(LoginHandler.PRINCIPAL_NAME_KEY));

    if (subject == null && (principal != null || principalName != null)) {
      subject = new Subject();
      if (principal == null) {
        principal = new UsernamePrincipal(principalName);
      }
      subject.getPrincipals().add(principal);
    }

    return subject;
  }
  /** {@inheritDoc} */
  protected void processAttribute(XMLObject samlObject, Attr attribute)
      throws UnmarshallingException {
    EntityDescriptor entityDescriptor = (EntityDescriptor) samlObject;

    if (attribute.getLocalName().equals(EntityDescriptor.ENTITY_ID_ATTRIB_NAME)) {
      entityDescriptor.setEntityID(attribute.getValue());
    } else if (attribute.getLocalName().equals(EntityDescriptor.ID_ATTRIB_NAME)) {
      entityDescriptor.setID(attribute.getValue());
      attribute.getOwnerElement().setIdAttributeNode(attribute, true);
    } else if (attribute.getLocalName().equals(TimeBoundSAMLObject.VALID_UNTIL_ATTRIB_NAME)
        && !DatatypeHelper.isEmpty(attribute.getValue())) {
      entityDescriptor.setValidUntil(
          new DateTime(attribute.getValue(), ISOChronology.getInstanceUTC()));
    } else if (attribute.getLocalName().equals(CacheableSAMLObject.CACHE_DURATION_ATTRIB_NAME)) {
      entityDescriptor.setCacheDuration(XMLHelper.durationToLong(attribute.getValue()));
    } else {
      QName attribQName = XMLHelper.getNodeQName(attribute);
      if (attribute.isId()) {
        entityDescriptor.getUnknownAttributes().registerID(attribQName);
      }
      entityDescriptor.getUnknownAttributes().put(attribQName, attribute.getValue());
    }
  }
 /**
  * Validates the ID attribute.
  *
  * @param request request to validate
  * @throws ValidationException if invalid
  */
 protected void validateID(RequestAbstractType request) throws ValidationException {
   if (DatatypeHelper.isEmpty(request.getID())) {
     throw new ValidationException("ID attribute must not be empty");
   }
 }
  /**
   * Completes the authentication process.
   *
   * <p>The principal name set by the authentication handler is retrieved and pushed in to the login
   * context, a Shibboleth session is created if needed, information indicating that the user has
   * logged into the service is recorded and finally control is returned back to the profile
   * handler.
   *
   * @param loginContext current login context
   * @param httpRequest current HTTP request
   * @param httpResponse current HTTP response
   */
  protected void completeAuthentication(
      LoginContext loginContext, HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
    LOG.debug("Completing user authentication process");

    Session idpSession = (Session) httpRequest.getAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE);

    try {
      // We allow a login handler to override the authentication method in the
      // event that it supports multiple methods
      String actualAuthnMethod =
          DatatypeHelper.safeTrimOrNullString(
              (String) httpRequest.getAttribute(LoginHandler.AUTHENTICATION_METHOD_KEY));
      if (actualAuthnMethod != null) {
        if (!loginContext.getRequestedAuthenticationMethods().isEmpty()
            && !loginContext.getRequestedAuthenticationMethods().contains(actualAuthnMethod)) {
          String msg =
              "Relying patry required an authentication method of "
                  + loginContext.getRequestedAuthenticationMethods()
                  + " but the login handler performed "
                  + actualAuthnMethod;
          LOG.error(msg);
          throw new AuthenticationException(msg);
        }
      } else {
        actualAuthnMethod = loginContext.getAttemptedAuthnMethod();
      }

      // Check to make sure the login handler did the right thing
      validateSuccessfulAuthentication(loginContext, httpRequest, actualAuthnMethod);
      if (loginContext.getAuthenticationFailure() != null) {
        returnToProfileHandler(httpRequest, httpResponse);
        return;
      }

      // Check for an overridden authn instant.
      DateTime actualAuthnInstant =
          (DateTime) httpRequest.getAttribute(LoginHandler.AUTHENTICATION_INSTANT_KEY);

      // Get the Subject from the request. If force authentication was required then make sure the
      // Subject identifies the same user that authenticated before
      Subject subject = getLoginHandlerSubject(httpRequest);
      if (loginContext.isForceAuthRequired()) {
        validateForcedReauthentication(idpSession, actualAuthnMethod, subject);

        // Reset the authn instant.
        if (actualAuthnInstant == null) {
          actualAuthnInstant = new DateTime();
        }
      }

      loginContext.setPrincipalAuthenticated(true);
      updateUserSession(
          loginContext, subject, actualAuthnMethod, actualAuthnInstant, httpRequest, httpResponse);
      LOG.debug(
          "User {} authenticated with method {}",
          loginContext.getPrincipalName(),
          loginContext.getAuthenticationMethod());
    } catch (AuthenticationException e) {
      LOG.error("Authentication failed with the error:", e);
      loginContext.setPrincipalAuthenticated(false);
      loginContext.setAuthenticationFailure(e);
    }

    returnToProfileHandler(httpRequest, httpResponse);
  }