/** @see {@link ParserNamespaceSupport#parse(XMLEventReader)} */ public Object parse(XMLEventReader xmlEventReader) throws ParsingException { // Get the startelement StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader); StaxParserUtil.validate(startElement, RESPONSE); ResponseType response = (ResponseType) parseBaseAttributes(startElement); while (xmlEventReader.hasNext()) { // Let us peek at the next start element startElement = StaxParserUtil.peekNextStartElement(xmlEventReader); if (startElement == null) break; String elementName = StaxParserUtil.getStartElementName(startElement); if (JBossSAMLConstants.ISSUER.get().equals(elementName)) { startElement = StaxParserUtil.getNextStartElement(xmlEventReader); NameIDType issuer = new NameIDType(); issuer.setValue(StaxParserUtil.getElementText(xmlEventReader)); response.setIssuer(issuer); } else if (JBossSAMLConstants.SIGNATURE.get().equals(elementName)) { Element sig = StaxParserUtil.getDOMElement(xmlEventReader); response.setSignature(sig); } else if (JBossSAMLConstants.ASSERTION.get().equals(elementName)) { SAMLAssertionParser assertionParser = new SAMLAssertionParser(); response.addAssertion( new RTChoiceType((AssertionType) assertionParser.parse(xmlEventReader))); } else if (JBossSAMLConstants.STATUS.get().equals(elementName)) { response.setStatus(parseStatus(xmlEventReader)); } else if (JBossSAMLConstants.ENCRYPTED_ASSERTION.get().equals(elementName)) { Element encryptedAssertion = StaxParserUtil.getDOMElement(xmlEventReader); response.addAssertion(new RTChoiceType(new EncryptedAssertionType(encryptedAssertion))); } else throw logger.parserUnknownTag(elementName, startElement.getLocation()); } return response; }
private String getAttributeValue(Object attrValue) { String value = null; if (attrValue instanceof String) { value = (String) attrValue; } else if (attrValue instanceof Node) { Node roleNode = (Node) attrValue; value = roleNode.getFirstChild().getNodeValue(); } else if (attrValue instanceof NameIDType) { NameIDType nameIdType = (NameIDType) attrValue; value = nameIdType.getValue(); } else { log.warn( "Unable to extract unknown SAML assertion attribute value type: " + attrValue.getClass().getName()); } return value; }
/** * Parse a {@code NameIDType} * * @param xmlEventReader * @return * @throws ParsingException */ public static NameIDType parseNameIDType(XMLEventReader xmlEventReader) throws ParsingException { StartElement nameIDElement = StaxParserUtil.getNextStartElement(xmlEventReader); NameIDType nameID = new NameIDType(); Attribute nameQualifier = nameIDElement.getAttributeByName(new QName(JBossSAMLConstants.NAME_QUALIFIER.get())); if (nameQualifier != null) { nameID.setNameQualifier(StaxParserUtil.getAttributeValue(nameQualifier)); } Attribute format = nameIDElement.getAttributeByName(new QName(JBossSAMLConstants.FORMAT.get())); if (format != null) { nameID.setFormat(URI.create(StaxParserUtil.getAttributeValue(format))); } Attribute spProvidedID = nameIDElement.getAttributeByName(new QName(JBossSAMLConstants.SP_PROVIDED_ID.get())); if (spProvidedID != null) { nameID.setSPProvidedID(StaxParserUtil.getAttributeValue(spProvidedID)); } Attribute spNameQualifier = nameIDElement.getAttributeByName(new QName(JBossSAMLConstants.SP_NAME_QUALIFIER.get())); if (spNameQualifier != null) { nameID.setSPNameQualifier(StaxParserUtil.getAttributeValue(spNameQualifier)); } String nameIDValue = StaxParserUtil.getElementText(xmlEventReader); nameID.setValue(nameIDValue); return nameID; }
protected Response loginRequest( String relayState, AuthnRequestType requestAbstractType, ClientModel client) { SamlClient samlClient = new SamlClient(client); // validate destination if (requestAbstractType.getDestination() != null && !uriInfo.getAbsolutePath().equals(requestAbstractType.getDestination())) { event.detail(Details.REASON, "invalid_destination"); event.error(Errors.INVALID_SAML_AUTHN_REQUEST); return ErrorPage.error(session, Messages.INVALID_REQUEST); } String bindingType = getBindingType(requestAbstractType); if (samlClient.forcePostBinding()) bindingType = SamlProtocol.SAML_POST_BINDING; String redirect = null; URI redirectUri = requestAbstractType.getAssertionConsumerServiceURL(); if (redirectUri != null && !"null".equals(redirectUri)) { // "null" is for testing purposes redirect = RedirectUtils.verifyRedirectUri(uriInfo, redirectUri.toString(), realm, client); } else { if (bindingType.equals(SamlProtocol.SAML_POST_BINDING)) { redirect = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE); } else { redirect = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_REDIRECT_ATTRIBUTE); } if (redirect == null) { redirect = client.getManagementUrl(); } } if (redirect == null) { event.error(Errors.INVALID_REDIRECT_URI); return ErrorPage.error(session, Messages.INVALID_REDIRECT_URI); } ClientSessionModel clientSession = session.sessions().createClientSession(realm, client); clientSession.setAuthMethod(SamlProtocol.LOGIN_PROTOCOL); clientSession.setRedirectUri(redirect); clientSession.setAction(ClientSessionModel.Action.AUTHENTICATE.name()); clientSession.setNote(SamlProtocol.SAML_BINDING, bindingType); clientSession.setNote(GeneralConstants.RELAY_STATE, relayState); clientSession.setNote(SamlProtocol.SAML_REQUEST_ID, requestAbstractType.getID()); // Handle NameIDPolicy from SP NameIDPolicyType nameIdPolicy = requestAbstractType.getNameIDPolicy(); if (nameIdPolicy != null && !samlClient.forceNameIDFormat()) { String nameIdFormat = nameIdPolicy.getFormat().toString(); // TODO: Handle AllowCreate too, relevant for persistent NameID. if (isSupportedNameIdFormat(nameIdFormat)) { clientSession.setNote(GeneralConstants.NAMEID_FORMAT, nameIdFormat); } else { event.detail(Details.REASON, "unsupported_nameid_format"); event.error(Errors.INVALID_SAML_AUTHN_REQUEST); return ErrorPage.error(session, Messages.UNSUPPORTED_NAME_ID_FORMAT); } } // Reading subject/nameID in the saml request SubjectType subject = requestAbstractType.getSubject(); if (subject != null) { SubjectType.STSubType subType = subject.getSubType(); if (subType != null) { BaseIDAbstractType baseID = subject.getSubType().getBaseID(); if (baseID != null && baseID instanceof NameIDType) { NameIDType nameID = (NameIDType) baseID; clientSession.setNote(OIDCLoginProtocol.LOGIN_HINT_PARAM, nameID.getValue()); } } } return newBrowserAuthentication( clientSession, requestAbstractType.isIsPassive(), redirectToAuthentication); }
protected AuthOutcome handleLoginResponse( ResponseType responseType, OnSessionCreated onCreateSession) { AssertionType assertion = null; try { assertion = AssertionUtil.getAssertion(responseType, deployment.getDecryptionKey()); if (AssertionUtil.hasExpired(assertion)) { return initiateLogin(); } } catch (Exception e) { log.error("Error extracting SAML assertion: " + e.getMessage()); challenge = new AuthChallenge() { @Override public boolean challenge(HttpFacade exchange) { SamlAuthenticationError error = new SamlAuthenticationError(SamlAuthenticationError.Reason.EXTRACTION_FAILURE); exchange.getRequest().setError(error); exchange.getResponse().sendError(403); return true; } @Override public int getResponseCode() { return 403; } }; } SubjectType subject = assertion.getSubject(); SubjectType.STSubType subType = subject.getSubType(); NameIDType subjectNameID = (NameIDType) subType.getBaseID(); String principalName = subjectNameID.getValue(); final Set<String> roles = new HashSet<>(); MultivaluedHashMap<String, String> attributes = new MultivaluedHashMap<>(); MultivaluedHashMap<String, String> friendlyAttributes = new MultivaluedHashMap<>(); Set<StatementAbstractType> statements = assertion.getStatements(); for (StatementAbstractType statement : statements) { if (statement instanceof AttributeStatementType) { AttributeStatementType attributeStatement = (AttributeStatementType) statement; List<AttributeStatementType.ASTChoiceType> attList = attributeStatement.getAttributes(); for (AttributeStatementType.ASTChoiceType obj : attList) { AttributeType attr = obj.getAttribute(); if (isRole(attr)) { List<Object> attributeValues = attr.getAttributeValue(); if (attributeValues != null) { for (Object attrValue : attributeValues) { String role = getAttributeValue(attrValue); log.debugv("Add role: {0}", role); roles.add(role); } } } else { List<Object> attributeValues = attr.getAttributeValue(); if (attributeValues != null) { for (Object attrValue : attributeValues) { String value = getAttributeValue(attrValue); if (attr.getName() != null) { attributes.add(attr.getName(), value); } if (attr.getFriendlyName() != null) { friendlyAttributes.add(attr.getFriendlyName(), value); } } } } } } } if (deployment.getPrincipalNamePolicy() == SamlDeployment.PrincipalNamePolicy.FROM_ATTRIBUTE) { if (deployment.getPrincipalAttributeName() != null) { String attribute = attributes.getFirst(deployment.getPrincipalAttributeName()); if (attribute != null) principalName = attribute; else { attribute = friendlyAttributes.getFirst(deployment.getPrincipalAttributeName()); if (attribute != null) principalName = attribute; } } } AuthnStatementType authn = null; for (Object statement : assertion.getStatements()) { if (statement instanceof AuthnStatementType) { authn = (AuthnStatementType) statement; break; } } URI nameFormat = subjectNameID.getFormat(); String nameFormatString = nameFormat == null ? JBossSAMLURIConstants.NAMEID_FORMAT_UNSPECIFIED.get() : nameFormat.toString(); final SamlPrincipal principal = new SamlPrincipal( assertion, principalName, principalName, nameFormatString, attributes, friendlyAttributes); String index = authn == null ? null : authn.getSessionIndex(); final String sessionIndex = index; SamlSession account = new SamlSession(principal, roles, sessionIndex); sessionStore.saveAccount(account); onCreateSession.onSessionCreated(account); // redirect to original request, it will be restored String redirectUri = sessionStore.getRedirectUri(); if (redirectUri != null) { facade.getResponse().setHeader("Location", redirectUri); facade.getResponse().setStatus(302); facade.getResponse().end(); } else { log.debug("IDP initiated invocation"); } log.debug("AUTHENTICATED authn"); return AuthOutcome.AUTHENTICATED; }