Search in sources :

Example 16 with LogoutRequestType

use of org.keycloak.dom.saml.v2.protocol.LogoutRequestType in project keycloak by keycloak.

the class SAMLSloRequestParser method instantiateElement.

@Override
protected LogoutRequestType instantiateElement(XMLEventReader xmlEventReader, StartElement startElement) throws ParsingException {
    SAMLParserUtil.validateAttributeValue(startElement, SAMLProtocolQNames.ATTR_VERSION, VERSION_2_0);
    String id = StaxParserUtil.getRequiredAttributeValue(startElement, SAMLProtocolQNames.ATTR_ID);
    XMLGregorianCalendar issueInstant = XMLTimeUtil.parse(StaxParserUtil.getRequiredAttributeValue(startElement, SAMLProtocolQNames.ATTR_ISSUE_INSTANT));
    LogoutRequestType logoutRequest = new LogoutRequestType(id, issueInstant);
    super.parseBaseAttributes(startElement, logoutRequest);
    logoutRequest.setReason(StaxParserUtil.getAttributeValue(startElement, SAMLProtocolQNames.ATTR_REASON));
    logoutRequest.setNotOnOrAfter(StaxParserUtil.getXmlTimeAttributeValue(startElement, SAMLProtocolQNames.ATTR_NOT_ON_OR_AFTER));
    return logoutRequest;
}
Also used : XMLGregorianCalendar(javax.xml.datatype.XMLGregorianCalendar) LogoutRequestType(org.keycloak.dom.saml.v2.protocol.LogoutRequestType)

Example 17 with LogoutRequestType

use of org.keycloak.dom.saml.v2.protocol.LogoutRequestType in project keycloak by keycloak.

the class SAMLSloRequestParser method processSubElement.

@Override
protected void processSubElement(XMLEventReader xmlEventReader, LogoutRequestType target, SAMLProtocolQNames element, StartElement elementDetail) throws ParsingException {
    switch(element) {
        case ISSUER:
        case SIGNATURE:
        case EXTENSIONS:
            parseCommonElements(element, elementDetail, xmlEventReader, target);
            break;
        case NAMEID:
            NameIDType nameID = SAMLParserUtil.parseNameIDType(xmlEventReader);
            target.setNameID(nameID);
            break;
        case ENCRYPTED_ID:
            Element domElement = StaxParserUtil.getDOMElement(xmlEventReader);
            target.setEncryptedID(new EncryptedElementType(domElement));
            break;
        case SESSION_INDEX:
            StaxParserUtil.getNextStartElement(xmlEventReader);
            target.addSessionIndex(StaxParserUtil.getElementText(xmlEventReader));
            break;
        default:
            throw LOGGER.parserUnknownTag(StaxParserUtil.getElementName(elementDetail), elementDetail.getLocation());
    }
}
Also used : Element(org.w3c.dom.Element) StartElement(javax.xml.stream.events.StartElement) NameIDType(org.keycloak.dom.saml.v2.assertion.NameIDType) EncryptedElementType(org.keycloak.dom.saml.v2.assertion.EncryptedElementType)

Example 18 with LogoutRequestType

use of org.keycloak.dom.saml.v2.protocol.LogoutRequestType in project keycloak by keycloak.

the class SamlProtocol method createLogoutRequest.

protected LogoutRequestType createLogoutRequest(String logoutUrl, AuthenticatedClientSessionModel clientSession, ClientModel client, NodeGenerator... extensions) throws ConfigurationException {
    // build userPrincipal with subject used at login
    SAML2LogoutRequestBuilder logoutBuilder = new SAML2LogoutRequestBuilder().assertionExpiration(realm.getAccessCodeLifespan()).issuer(getResponseIssuer(realm)).userPrincipal(clientSession.getNote(SAML_NAME_ID), clientSession.getNote(SAML_NAME_ID_FORMAT)).destination(logoutUrl);
    String sessionIndex = SamlSessionUtils.getSessionIndex(clientSession);
    logoutBuilder.sessionIndex(sessionIndex);
    for (NodeGenerator extension : extensions) {
        logoutBuilder.addExtension(extension);
    }
    LogoutRequestType logoutRequest = logoutBuilder.createLogoutRequest();
    for (Iterator<SamlAuthenticationPreprocessor> it = SamlSessionUtils.getSamlAuthenticationPreprocessorIterator(session); it.hasNext(); ) {
        logoutRequest = it.next().beforeSendingLogoutRequest(logoutRequest, clientSession.getUserSession(), clientSession);
    }
    return logoutRequest;
}
Also used : LogoutRequestType(org.keycloak.dom.saml.v2.protocol.LogoutRequestType) SamlAuthenticationPreprocessor(org.keycloak.protocol.saml.preprocessor.SamlAuthenticationPreprocessor) SAML2LogoutRequestBuilder(org.keycloak.saml.SAML2LogoutRequestBuilder) NodeGenerator(org.keycloak.saml.SamlProtocolExtensionsAwareBuilder.NodeGenerator)

Example 19 with LogoutRequestType

use of org.keycloak.dom.saml.v2.protocol.LogoutRequestType in project keycloak by keycloak.

the class SamlProtocol method backchannelLogout.

@Override
public Response backchannelLogout(UserSessionModel userSession, AuthenticatedClientSessionModel clientSession) {
    ClientModel client = clientSession.getClient();
    SamlClient samlClient = new SamlClient(client);
    String logoutUrl = getLogoutServiceUrl(session, client, SAML_POST_BINDING, true);
    if (logoutUrl == null) {
        logger.warnf("Can't do backchannel logout. No SingleLogoutService POST Binding registered for client: %s", client.getClientId());
        return Response.serverError().build();
    }
    String logoutRequestString = null;
    try {
        LogoutRequestType logoutRequest = createLogoutRequest(logoutUrl, clientSession, client);
        JaxrsSAML2BindingBuilder binding = createBindingBuilder(samlClient, false);
        // This is POST binding, hence KeyID is included in dsig:KeyInfo/dsig:KeyName, no need to add <samlp:Extensions> element
        logoutRequestString = binding.postBinding(SAML2Request.convert(logoutRequest)).encoded();
    } catch (Exception e) {
        logger.warn("failed to send saml logout", e);
        return Response.serverError().build();
    }
    CloseableHttpClient httpClient = session.getProvider(HttpClientProvider.class).getHttpClient();
    for (int i = 0; i < 2; i++) {
        // follow redirects once
        try {
            List<NameValuePair> formparams = new ArrayList<NameValuePair>();
            formparams.add(new BasicNameValuePair(GeneralConstants.SAML_REQUEST_KEY, logoutRequestString));
            // for Picketlink
            formparams.add(new BasicNameValuePair("BACK_CHANNEL_LOGOUT", "BACK_CHANNEL_LOGOUT"));
            // todo remove
            // this
            UrlEncodedFormEntity form = new UrlEncodedFormEntity(formparams, "UTF-8");
            HttpPost post = new HttpPost(logoutUrl);
            post.setEntity(form);
            try (CloseableHttpResponse response = httpClient.execute(post)) {
                try {
                    int status = response.getStatusLine().getStatusCode();
                    if (status == 302 && !logoutUrl.endsWith("/")) {
                        String redirect = response.getFirstHeader(HttpHeaders.LOCATION).getValue();
                        String withSlash = logoutUrl + "/";
                        if (withSlash.equals(redirect)) {
                            logoutUrl = withSlash;
                            continue;
                        }
                    }
                } finally {
                    EntityUtils.consumeQuietly(response.getEntity());
                }
            }
        } catch (IOException e) {
            logger.warn("failed to send saml logout", e);
            return Response.serverError().build();
        }
        break;
    }
    return Response.ok().build();
}
Also used : CloseableHttpClient(org.apache.http.impl.client.CloseableHttpClient) NameValuePair(org.apache.http.NameValuePair) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) HttpPost(org.apache.http.client.methods.HttpPost) ArrayList(java.util.ArrayList) LogoutRequestType(org.keycloak.dom.saml.v2.protocol.LogoutRequestType) UrlEncodedFormEntity(org.apache.http.client.entity.UrlEncodedFormEntity) IOException(java.io.IOException) ParsingException(org.keycloak.saml.common.exceptions.ParsingException) ProcessingException(org.keycloak.saml.common.exceptions.ProcessingException) ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) IOException(java.io.IOException) ClientModel(org.keycloak.models.ClientModel) HttpClientProvider(org.keycloak.connections.httpclient.HttpClientProvider) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) CloseableHttpResponse(org.apache.http.client.methods.CloseableHttpResponse)

Example 20 with LogoutRequestType

use of org.keycloak.dom.saml.v2.protocol.LogoutRequestType in project keycloak by keycloak.

the class SAMLRequestWriter method write.

/**
 * Write a {@code LogoutRequestType} to stream
 *
 * @param logOutRequest
 *
 * @throws ProcessingException
 */
public void write(LogoutRequestType logOutRequest) throws ProcessingException {
    StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.LOGOUT_REQUEST.get(), PROTOCOL_NSURI.get());
    StaxUtil.writeNameSpace(writer, PROTOCOL_PREFIX, PROTOCOL_NSURI.get());
    StaxUtil.writeNameSpace(writer, ASSERTION_PREFIX, ASSERTION_NSURI.get());
    StaxUtil.writeDefaultNameSpace(writer, ASSERTION_NSURI.get());
    // Attributes
    StaxUtil.writeAttribute(writer, JBossSAMLConstants.ID.get(), logOutRequest.getID());
    StaxUtil.writeAttribute(writer, JBossSAMLConstants.VERSION.get(), logOutRequest.getVersion());
    StaxUtil.writeAttribute(writer, JBossSAMLConstants.ISSUE_INSTANT.get(), logOutRequest.getIssueInstant().toString());
    URI destination = logOutRequest.getDestination();
    if (destination != null) {
        StaxUtil.writeAttribute(writer, JBossSAMLConstants.DESTINATION.get(), destination.toASCIIString());
    }
    String consent = logOutRequest.getConsent();
    if (StringUtil.isNotNull(consent))
        StaxUtil.writeAttribute(writer, JBossSAMLConstants.CONSENT.get(), consent);
    NameIDType issuer = logOutRequest.getIssuer();
    write(issuer, new QName(ASSERTION_NSURI.get(), JBossSAMLConstants.ISSUER.get(), ASSERTION_PREFIX));
    Element signature = logOutRequest.getSignature();
    if (signature != null) {
        StaxUtil.writeDOMElement(writer, signature);
    }
    ExtensionsType extensions = logOutRequest.getExtensions();
    if (extensions != null && !extensions.getAny().isEmpty()) {
        write(extensions);
    }
    NameIDType nameID = logOutRequest.getNameID();
    if (nameID != null) {
        write(nameID, new QName(ASSERTION_NSURI.get(), JBossSAMLConstants.NAMEID.get(), ASSERTION_PREFIX));
    }
    List<String> sessionIndexes = logOutRequest.getSessionIndex();
    for (String sessionIndex : sessionIndexes) {
        StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.SESSION_INDEX.get(), PROTOCOL_NSURI.get());
        StaxUtil.writeCharacters(writer, sessionIndex);
        StaxUtil.writeEndElement(writer);
        StaxUtil.flush(writer);
    }
    StaxUtil.writeEndElement(writer);
    StaxUtil.flush(writer);
}
Also used : QName(javax.xml.namespace.QName) Element(org.w3c.dom.Element) ExtensionsType(org.keycloak.dom.saml.v2.protocol.ExtensionsType) NameIDType(org.keycloak.dom.saml.v2.assertion.NameIDType) PROTOCOL_NSURI(org.keycloak.saml.common.constants.JBossSAMLURIConstants.PROTOCOL_NSURI) URI(java.net.URI) ASSERTION_NSURI(org.keycloak.saml.common.constants.JBossSAMLURIConstants.ASSERTION_NSURI)

Aggregations

LogoutRequestType (org.keycloak.dom.saml.v2.protocol.LogoutRequestType)18 Test (org.junit.Test)7 SAMLDocumentHolder (org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder)7 NameIDType (org.keycloak.dom.saml.v2.assertion.NameIDType)6 StatusResponseType (org.keycloak.dom.saml.v2.protocol.StatusResponseType)5 ProcessingException (org.keycloak.saml.common.exceptions.ProcessingException)4 SamlClientBuilder (org.keycloak.testsuite.util.SamlClientBuilder)4 Element (org.w3c.dom.Element)4 IOException (java.io.IOException)3 AuthnRequestType (org.keycloak.dom.saml.v2.protocol.AuthnRequestType)3 ResponseType (org.keycloak.dom.saml.v2.protocol.ResponseType)3 NodeGenerator (org.keycloak.saml.SamlProtocolExtensionsAwareBuilder.NodeGenerator)3 ConfigurationException (org.keycloak.saml.common.exceptions.ConfigurationException)3 ParsingException (org.keycloak.saml.common.exceptions.ParsingException)3 POST (org.keycloak.testsuite.util.SamlClient.Binding.POST)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 URI (java.net.URI)2 QName (javax.xml.namespace.QName)2 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)2 DOMSource (javax.xml.transform.dom.DOMSource)2