I am doing logins to Microsoft Sharepoint Online through an AD-Sycned ADFS using SAML1.1 and WS-federation.
I obtain a saml assertion first from ADFS. Then I submit a web request:
HTTP POST: https://login.microsoftonline.com/login.srf
Content-Type: application/x-www-form-urlencoded
With Form:
wa
= wsignin1.0
wctx
= my web ctx
wresult
= my saml assertion
Response: I clearly was able to log in, but instead of getting a page where I can obtain the token from, I get this page:
I found this page but my admins won't let me make the change it suggests which is company wide: https://cloudblogs.microsoft.com/enterprisemobility/2017/09/19/fewer-login-prompts-the-new-keep-me-signed-in-experience-for-azure-ad-is-in-preview/
How can I bypass this response during ADFS ws federated login?
Had to do what everyone else does in this situation when using Microsoft's terribly undocumented api's is to use fiddler to find out what to do.
Basically I turned on Fiddler, enabled HTTPS decryption support, then ran a login from an incognito browser window.
This shows me what form Post to emulate.
The following java code is what I came up with as a result, and it works:
Map configMap = getRememberMePageConfigMap(wsfedRes);
if (configMap != null) {
String sFT = (String) configMap.get("sFT");
String sFTName = (String) configMap.get("sFTName");
String ctx = (String) configMap.get("sCtx");
if (StringUtils.isNotBlank(sFT) && StringUtils.isNotBlank(sFTName) && StringUtils.isNotBlank(ctx)) {
LOG.info("Found the \"Remember Me\" page when we requested ws-federated auth token. Bypassing it.");
HttpPost rememberMePost = new HttpPost(MICROSOFT_ONLINE_LOGIN_KMSI_URL);
List<NameValuePair> wsFedFormParams = new ArrayList<>(3);
wsFedFormParams.add(new BasicNameValuePair(sFTName, sFT));
wsFedFormParams.add(new BasicNameValuePair("ctx", ctx));
wsFedFormParams.add(new BasicNameValuePair("LoginOptions", "0"));
rememberMePost.setHeader("Content-Type", "application/x-www-form-urlencoded");
rememberMePost.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
rememberMePost.setEntity(new UrlEncodedFormEntity(wsFedFormParams));
try (CloseableHttpResponse response = client.execute(rememberMePost)) {
String content = IOUtils.toString(response.getEntity().getContent(), "UTF-8");
if (diagnosticMode) {
LOG.info("After posting to {} to bypass the \"Remember me\" page, got statusCode={}, response={}",
MICROSOFT_ONLINE_LOGIN_KMSI_URL, response.getStatusLine().getStatusCode(), content);
}
return content;
}
}
}
Where getRememberMePageConfigMap is
Map getRememberMePageConfigMap(String wsfedRes) throws IOException {
String lines[] = wsfedRes.split("\\r?\\n");
for (String line : lines) {
if (line.startsWith("$Config=")) {
String jsonToParse = line.substring("$Config=".length());
return OBJECT_MAPPER.readValue(jsonToParse, Map.class);
}
}
return null;
}
This extra request correctly bypasses the form.