OKTA多因素认证+Java+RestAssured:loginstep-upredirect总是通过RESTAssured返回403。

问题描述 投票:0回答:1

我正试图使用Java的RestAssured API来验证进入OKTA的身份。问题的认证类型是多因素的,虽然我在Google Chrome浏览器中总是能够让这种认证成功,但在RestAssured中,尽管匹配了所有的请求头和cookie,却始终以403失败。我的最终目标是获得不记名认证令牌,以便能够在登录后运行服务。

基本上,这是我调用的服务顺序。

1) [redacted]apiv1authn; 我提供我的用户名和密码,以及一些字母数字状态令牌。(我使用了一个围绕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服务[redacted]apiv1authnfactors,并提供安全问题的答案。(这也会成功返回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]loginstep-upredirect?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}传递进来的token是否合法。当这个参数没有通过RestAssured API传递进来时,我总是得到400,所以我知道这个方法调用是区分状态令牌是否传递进来的。

我的问题是:在上面的一系列步骤中,我是否有什么值得注意的地方遗漏了,导致总是通过一种媒介返回403,而不是通过Web浏览器?是否有什么东西可以防止使用RestAssured API进行验证?如果是这样,我是否有其他途径可以获得承载令牌?

java rest-assured okta okta-api multi-factor-authentication
1个回答
0
投票

我想到了几件事。

1.) 你的响应是否包含响应#2中的上一步链接?https:/developer.okta.comdocsreferenceapiauthn#response-example-after-authentication-and-mfa-are-complete-for-step-up-authentication-with-okta-session。

2.) 如果可能的话,我建议使用OAuth流(或SAML),而不是使用Authn API。

3.) Authn API是一个状态机,你不能总是假设你可以按照这个顺序执行这些请求。

Okta也有一个Authn SDK。https:/github.comoktaokta-auth-java。 (但我们再次建议尽可能使用OAuth)

© www.soinside.com 2019 - 2024. All rights reserved.