Search code examples
wso2saml-2.0wso2-identity-server

Authenticate against WSO2 Identity Server with no browser and get SAML2 assertion message


I am trying to setup a service provider that uses WSO2 IS for authentication via SAML2. Now, wehave a use-case in which the user is a machine (i.e. an external program) that needs to access the service provider. Since the user is a machine, there is no browser and cannot use the WSO2 login form to complete the authentication steps, though it has been given a username and password since it is still a user.

My question is how can this non-GUI user participate in the SAML2 workflow (specifically pass credentials to WSO2 to obtain a SAMLV2 Assertion message) and access the service provider?

I tried to do the following as a simulation but I failed

1) curl -v -k http://localhost:8000/service_provider/login
2) Extracting the SAML message from the response:
    curl --user username:password -v  -k https://localhost:9443/samlsso?SAMLRequest=<ENCODED_REQUEST>

Basically, I was expecting to get a redirect response from WSO2 back to the service provider with SAML assertion message, but instead I got the following: https://localhost:9443/authenticationendpoint/login.do;jsessionid=7QON18982323HWIH?commonAuthCallerPath=%2Fsamlsso&forceAuth=false&passiveAuth=false&tenantDomain=carbon.super&sessionDataKey=122JhQ-JQOJ-H8123&relyingParty=test-saml2&type=samlsso&sp=test&isSaaSApp=false&authenticators=BasicAuthenticator:LOCAL, which is the same url that is used when a human user authenticates using a browser.

I also tried using HTTP-POST Binding with "sectoken" form param as suggested in this article: http://xacmlinfo.org/2015/02/12/sso-without-identity-provider-login-page/ . But it didn't work either.

I also tried making SOAP requests to WSO2's AuthenticationAdminHttpsSoap12Endpoint service, specifically the "login" method. I used the JSESSIONID I got from the SOAP response to the above steps but the effect was the same. This is not a surprise to me since WSO2 does not use JSESSIONID to check if you are authenticated already (at least not for trying to grab SAML responses).


Solution

    1. Get login form

    Request: curl -v http://localhost:8000/service_provider/login

    From the response, extract SAMLRequest and SSOAuthSessionID (if RelayState is present extract it too)

    1. Send SAML request to IDP using extracted values in step 1 (In browser this will happen through redirection)

    Request Endpoint : https://<is_host>:9443/samlsso

    Verb :post
    Content-Type:application/x-www-form-urlencoded
    Parameters:[
    SAMLRequest:<value from previous step>,
    SSOAuthSessionID:<value from previous step>,
    RelayState :<value from previous step>]
    

    The response will give IS login page. Extract sessionDataKey from that.

    1. Login by providing user name and password

    Reqeust Endpoint: https://<is_host>:9443/commonauth

    Content-Type:application/x-www-form-urlencoded
    Verb :post
    Parameters: [tocommonauth:true,username:xxxx,password:xxx,sessionDataKey:<extracted from previous step>]
    

    Extract the SAMLResponse from the response

    1. Post the SAML response to the ACS url of service provider