Question

Integration PingFederate with Sharepoint 2016 using JAVA - briefly explained here

Using Form based authentication i can able to connect to my sharepoint instance and can play around files and folder. But i try to change to my organisation instance with SSO authentication. I'm not getting security token. I have a doubt i'm going in right path or not? need some expert guidance on this

public String receiveSecurityToken(Long executionDateTime) throws TransformerException, URISyntaxException {
        RequestEntity<String> requestEntity = new RequestEntity<>(buildSecurityTokenRequestEnvelope(), HttpMethod.POST,
                new URI(sharePointProperties.getEndpointToken() + "/extSTS.srf"));

        log.debug("Token Type: " + requestEntity.getType().toString() + " - URL: " + requestEntity.getUrl());
        log.debug("Token Request: " + requestEntity.getBody());

        ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);

        log.debug("Token Response: " + responseEntity.getBody());

        DOMResult result = new DOMResult();
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.transform(new StringSource(responseEntity.getBody()), result);
        Document definitionDocument = (Document) result.getNode();

        String securityToken = xPathExpression.evaluateAsString(definitionDocument);
        if (StringUtils.isBlank(securityToken)) {
            // throw new SharePointAuthenticationException("Unable to
            // authenticate: empty token");
            throw new TransformerException("Unable to authenticate: empty token");
        }
        log.debug("Microsoft Online respond with Token: {}", securityToken);
        return securityToken;
    }

Framing SOAP envelope

private String buildSecurityTokenRequestEnvelope() {
        String envelopeTemplate = "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\" xmlns:u=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"> <s:Header>  <a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action>  <a:ReplyTo> <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>  </a:ReplyTo> <a:To s:mustUnderstand=\"1\">https://login.microsoftonline.com/extSTS.srf</a:To> <o:Security s:mustUnderstand=\"1\"  xmlns:o=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"> <o:UsernameToken>  <o:Username>%s</o:Username>  <o:Password>%s</o:Password> </o:UsernameToken>  </o:Security> </s:Header><s:Body><t:RequestSecurityToken xmlns:t=\"http://schemas.xmlsoap.org/ws/2005/02/trust\"><wsp:AppliesTo xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\"><a:EndpointReference><a:Address>"
                + sharePointProperties.getEndpointDomain()
                + "</a:Address></a:EndpointReference></wsp:AppliesTo><t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType>  <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType> <t:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</t:TokenType></t:RequestSecurityToken></s:Body></s:Envelope>";
        return String.format(envelopeTemplate, sharePointProperties.getUsername(), sharePointProperties.getPassword());
    }

Server Logs: Error inicial: Unable to authenticate: empty token

Response in postman:

[
    {
        "code": "Error",
        "value": "Unable to authenticate: empty token"
    }
]
Was it helpful?

Solution

I am not a Java programmer but based on quick read it seems to be connecting to SharePoint Online. This will not work in your case. If I understand correctly you want to connect to SharePoint 2016 configured with PingFederate SSO using user name and password (let me know if I am wrong).

Using Windows Auth

I would suggest authenticating through windows authentication from your application to simplify your app. Your administrator would have configured alternate url that uses windows auth for services like search to work. You can leverage that url when connecting to SharePoint. If you have mixed mode configured on same url, then add 'X-FORMS_BASED_AUTH_ACCEPTED' header with value 'f' in your request to force SharePoint to use windows auth.

Using PingFederate

If you have to use PingFederate, there are several steps involved in authenticating to SharePoint using PingFederate.

  1. Configure ws-trust on the pingfederate connection on the pingfederate console. This can be configured by your pingfederate administrator.

  2. Connect to pingfederate ws-trust endpoint to retrieve saml for a given username and password. The url should be https://your_ping_instance/idp/sts.wst. There are several examples posted on pingfed website and github which you should be able to lookup. I cannot those links here as I cannot validate java code.

Retrieve the saml from the response

  1. Post the saml to https://your_sharepoint_site/_layouts/Authenticate.aspx to retrieve FedAuth value

Take a look at the method 'TransformSamlTokenToFedAuth' at this link, which is in c#. The value of 'relyingPartyIdentifier' should be partner service identifier on pingfederate console for your connection.

  1. Build a cookie with value above fedauth value. See this link at the end of the method 'GetFedAuthCookie' for sample c# code.

  2. Insert that cookie into every request to SharePoint Api.

Unfortunately I do not program in Java, so do not have any java sample code. But you should be able to translate the code into Java.

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top