我正在尝试使用Java的RestAssured API向OKTA进行身份验证。有问题的身份验证类型是多因素的,尽管我始终可以使该身份验证在Google Chrome中获得成功,但尽管匹配所有请求标头和cookie,它在RestAssured中始终失败并带有403。我的最终目标是获得承载身份验证令牌,以便能够在登录后运行服务。
本质上,这是我正在调用的服务顺序:
1)[已编辑] / api / v1 / authn;我提供了用户名和密码,以及一些字母数字状态令牌。 (我在RestAssured的RequestSpecification周围使用包装器类:)此方法成功返回200:
// Create a brand new request to login using OKTA.
RequestWrapper requestWrapper11 = new RequestWrapper();
requestWrapper11.setResponseContentType(ContentType.JSON);
requestWrapper11.setacceptedContentType(ContentType.JSON);
requestWrapper11.setHTTPMethod(Method.POST);
requestWrapper11.setRequestPayload(new HashMap<>() {
{
put("username","[redacted]");
put("password","[redacted]");
put("options",new HashMap<String,Object>() {
{ put("warnBeforePasswordExpired",true); }
{ put("multiOptionalFactorEnroll",true); }
});
}
});
// Authenticate and get a brand new state token.
requestWrapper11.setBaseURL(new URL("[redacted]/api/v1/authn"));
ResponseWrapper response = requestWrapper11.executeAndGetResponse();
从此服务调用中,我将获取下一步中使用的状态令牌以及因子ID。
2)然后,我调用POST服务[已编辑] / api / v1 / authn / factors并提供安全问题的答案:(这也会成功返回200):
{answer:“ [redacted_1]”,statetoken:“ [state_token]”}
RequestWrapper requestWrapper2 = new RequestWrapper();
requestWrapper2.setResponseContentType(ContentType.JSON);
requestWrapper2.setacceptedContentType(ContentType.JSON);
requestWrapper2.setHTTPMethod(Method.POST);
requestWrapper2.setRequestPayload(new HashMap<>() {
{
put("answer","[redacted]");
put("statetoken",statetoken);
}
});
requestWrapper2.setOverrideQueryParams(new HashMap<>() {
{ put("rememberDevice",false); }
});
// Authenticate and get a brand new state token.
requestWrapper2.setBaseURL(new URL("[redacted]/api/v1/authn/factors/" + factorId + "/verify"));
3)最后,我进行GET调用[redacted] / login / step-up / redirect?statetoken = [state_token],以返回用于身份验证目的的特殊代码。
RequestWrapper requestWrapper4 = new RequestWrapper();
// requestWrapper4.setallowRedirects(true);
requestWrapper4.setOverrideQueryParams(new HashMap<>() {
{put("statetoken",statetoken); }
});
requestWrapper4.setHeader("Connection","Keep-Alive");
requestWrapper4.setHeader("Host","[redacted]");
requestWrapper4.setHeader("accept","text/html,application/xhtml+xml,application/xml" +
";q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
requestWrapper4.setHeader("accept-Encoding","gzip,deflate,br");
requestWrapper4.setHeader("accept-Language","en-US,en;q=0.9");
requestWrapper4.setHeader("Sec-Fetch-Dest","document");
requestWrapper4.setHeader("Sec-Fetch-Mode","navigate");
requestWrapper4.setHeader("Sec-Fetch-Site","same-origin");
requestWrapper4.addCookies(responseWrapper2.cookies);
requestWrapper4.addCookie("oktastatetoken",statetoken);
requestWrapper4.addCookie("t","summer");
requestWrapper4.addCookie("DT","DI0--aZ4ipPS8mFXhEWHFwXUw");
requestWrapper4.addCookie("ADRUM_BTa","R:0|g:dd262b5c-ae86-4a1d-86aa-a89b3fed2bed|n:Okta_6d5b1e30-d05a-4894-a37b-81b5f6c60e0e");
requestWrapper4.addCookie("ADRUM_BT1","R:0|i:617|e:41");
requestWrapper4.setHTTPMethod(Method.GET);
requestWrapper4.setHeader("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/81.0.4044.113 Safari/537.36");
requestWrapper4.setBaseURL(new URL("[redacted]/login/step-up/redirect"));
ResponseWrapper responseWrapper4 = requestWrapper4.executeAndGetResponse();
当我正常使用浏览器进行身份验证时,这三个服务调用将在浏览器中进行,而不会出现问题,并且都返回200或302。但是,每当我使用RestAssured API运行这些服务时,我总是在第三个服务上获得403无论作为查询参数{statetoken}传入的令牌是否合法,都将执行。当未通过RestAssured API传递此参数时,我总是得到400,因此我知道此方法调用可区分是否传递状态令牌。
我的问题是:在上述步骤中是否缺少使403总是通过一种媒介而不是通过Web浏览器返回的任何值得注意的东西?是否有适当的地方可以防止使用RestAssured API进行身份验证?如果是这样,我还有其他途径可以获取持票人令牌吗?