/** {@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()); } }
/** {@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); }
/** {@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); }