OIDC登录自动化测试

Automated test for OIDC Login

我已经为我的 java 应用程序构建了一个 OpenID Connect 登录(没有 spring)。现在我想对 OIDC 流程进行自动化测试。我使用 KeyCloak 作为授权服务器。 对于 OIDC,我的测试必须通过传递用户名和密码登录 keyloak 登录页面。为此,我使用 HtmlUnit 和一个简单的 http 服务器进行重定向。

// Setup http-server to recieve the code from the redirect    
HttpServer server = HttpServer.create(new InetSocketAddress(InetAddress.getLocalHost().getHostAddress(), 8001), 0);
    server.createContext("/oidc_test_callback", new HttpHandler() {
        @Override
        public void handle(HttpExchange exchange) throws IOException {
            String url = exchange.getRequestURI().toString();
            String parameter = "code=";
            String codeValue = url.substring(url.indexOf(parameter) + parameter.length());
            // continue the test with the code
        }
    });
    server.setExecutor(null); 
    server.start();
    
    // login with the dummy-user on the keyloak loginpage
    String url = ...; // the URL looks like http://keycloak:8080/auth/realms/testRealm/protocol/openid-connect/auth?client_id=myAppName&redirect_uri=http%3A%2F%2F192.168.202.102%3A8001%2Foidc_test_callback&response_type=code&scope=openid+profile&state=7944e52a-467a-4000-874b-ea4991dbeaeb&nonce=somecorrelationnonce&login_hint=&acr_values=
    try (WebClient webClient = new WebClient()) {
        webClient.getOptions().setCssEnabled(true);
        webClient.getOptions().setRedirectEnabled(true);
        webClient.getOptions().setJavaScriptEnabled(true);
        webClient.setAjaxController(new NicelyResynchronizingAjaxController());
        HtmlPage page = webClient.getPage(url);

        HtmlForm form = (HtmlForm) page.getElementById("kc-form-login");
        HtmlTextInput inputUsername = form.getInputByName("username");
        HtmlPasswordInput inputPassword = (HtmlPasswordInput) form.getInputByName("password");
        inputUsername.type("admin");
        inputPassword.type("admin");
        HtmlSubmitInput buttonLogin = (HtmlSubmitInput) form.getInputByName("login");
        buttonLogin.click();
    } catch (Exception ex) {
        Assertions.fail(ex);
    }

当我 运行 这段代码时,http 服务器没有收到任何东西。 看起来登录按钮没有正确执行。

这是来自 keycloak 登录页面的 html 代码:

<div id="kc-form">
  <div id="kc-form-wrapper">
        <form id="kc-form-login" onsubmit="login.disabled = true; return true;" action="http://keycloak:8080/auth/realms/testRealm/login-actions/authenticate?session_code=dIFFDFXC9YsXhiR0PLdfOjj-YcV-j_rZWr5DBVkQ8UU&amp;execution=108fb093-287d-4c18-b4a9-10a162e908ca&amp;client_id=UMS_Loginserver&amp;tab_id=tKYHYQvKb70" method="post">
            <div class="form-group">
                <label for="username" class="pf-c-form__label pf-c-form__label-text">Username or email</label>

                    <input tabindex="1" id="username" class="pf-c-form-control" name="username" value=""  type="text" autofocus autocomplete="off"
                           aria-invalid=""
                    />

            </div>

            <div class="form-group">
                <label for="password" class="pf-c-form__label pf-c-form__label-text">Password</label>

                <input tabindex="2" id="password" class="pf-c-form-control" name="password" type="password" autocomplete="off"
                       aria-invalid=""
                />
            </div>

            <div class="form-group login-pf-settings">
                <div id="kc-form-options">
                    </div>
                    <div class="">
                    </div>

              </div>

              <div id="kc-form-buttons" class="form-group">
                  <input type="hidden" id="id-hidden-input" name="credentialId" />
                  <input tabindex="4" class="pf-c-button pf-m-primary pf-m-block btn-lg" name="login" id="kc-login" type="submit" value="Sign In"/>
              </div>
        </form>
    </div>
</div>

我通过传递 正确的 用户凭据自行解决了......密码是“admin1”