Get authenticated cookie with SAML2 response


Introduction

In a WSO2 integration sometimes you might want to get authenticated to admin services from you Webapps to another Carbon server admin service without requesting the credentials or keeping the credentials in memory. For this you can use the authenticated SAML response to get the authenticated admin cookie and invoke those admin services in another carbon server.

Following code chunk explains how authenticated SAMLresponse is added as a Note in Catalina server session when the session is authenticated.

protected void authenticateSession(Request request, String sessionIndex, String username)
        throws Exception {
    //Register the specified Principal as being associated with the specified value for the sessionIndex on identifier.
    Principal principal = WebappTomcatUtils.getUserPrincipal(request, username);

    SingleSignOnEntry sso = lookup(sessionIndex);
    if (sso == null) {
        register(sessionIndex, principal, SAML_METHOD, username, "");
    }

    //Associate the specified single sign on identifier with the specified Session
    associate(sessionIndex, request.getSessionInternal(true));

    // Save the authenticated Principal in our session
    Session session = request.getSessionInternal(false);
    if (session != null) {
        session.setAuthType(SAML_METHOD);
        session.setPrincipal(principal);
        session.setNote(Constants.SAML_RESPONSE, request.getSession().getAttribute("saml_token"));
    }

    // set user is authenticated.
    HttpSession httpSession = request.getSession();
    this.setSessionAuthInfo(httpSession, (GenericPrincipal) principal, getTenantDomainFromUsername(username), SAML_METHOD);
}

Following method explains how we can get the authenticated cookie using SAML response.


public String authenticateWithSAML2Response(ConfigurationContext configContext,
                                                HttpServletRequest httpRequest,
                                            String backendServerURL,
                                            String username) throws AuthenticationException {
    if (username == null) {
        throw new AuthenticationException("Username is null. Failed to retrieve the username from the http request");
    }

    SAML2SSOAuthenticationServiceStub stub = null;
    try {
        stub = new SAML2SSOAuthenticationServiceStub(configContext, backendServerURL + SSO_AUTH_SERVICE);
        AuthnReqDTO authnReqDTO = new AuthnReqDTO();
        if (session == null) {
            throw new AuthenticationException("Session object is null");
        }
        authnReqDTO.setResponse((String) session.getNote(Constants.SAML_RESPONSE));
        // authnReqDTO.setUsername(username);
        boolean loggedIn = stub.login(authnReqDTO);
        String cookie;
        if (loggedIn) {
            cookie = (String) stub._getServiceClient().getServiceContext().getProperty(HTTPConstants.COOKIE_STRING);
            if (log.isDebugEnabled()) {
                log.debug("Logged in Cookie : " + cookie);
            }
            return cookie;
        } else {
            log.error("Login failure.");
            throw new AuthenticationException("Login failure.");
        }
    } catch (RemoteException e) {
        String errorMsg = "SAML2SSO Authentication Service Stub initialization failed. ";
        log.error(errorMsg, e);
        throw new AuthenticationException(errorMsg, e);
    } finally {
        if (stub != null) {
            try {
                stub.cleanup();
            } catch (RemoteException e) {
                log.error("Error while cleaning up SAML2SSOAuthenticationServiceStub", e);
            }
        }
    }
}

If this is failing with the following exception that means when passing SAML token to get admin cookie, Identity Server do audience restriction validation against the value inside  authenticators.xml ServiceProviderID parameter to make sure client is intended to use given SAML response.

[2015-04-06 16:22:24,179] ERROR {org.wso2.carbon.identity.authenticator.saml2.sso.SAML2SSOAuthenticator} -  Authentication Request is rejected. SAMLResponse AudienceRestriction validation failed.

To solve this you have to make sure when registering the service provider, add all the necessary audiences to it.

Comments

Popular Posts