java - 如何以编程方式验证 Spring Boot 端点?

标签 java spring-boot

在 Spring Boot 应用程序中,我启用一个端点,即 metrics 端点。同时,我不想将其公开,因此我使用以下设置对其进行了配置:

security.user.name=admin
security.user.password=ENC(l2y+PuJeGIOMshbv+ddZgK8lOe2TRdt9YIuMwB5g5Ws=)
security.basic.enabled=false

management.context-path=/manager
management.port=8082
management.address=127.0.0.2
management.security.enabled=false
management.security.roles=SUPERUSER
management.ssl.enabled=true
management.ssl.key-store=file:keystore.jks
management.ssl.key-password=ENC(l2y+PuJeGIOMshbv+ddZgK8lOe2TRdt9YIuMwB5g5Ws=)

endpoints.metrics.id=metrics
endpoints.metrics.sensitive=true
endpoints.metrics.enabled=true

基本上,如果有人尝试访问 https://127.0.0.2:8082/manager/metrics URI 抛出任何浏览器,那么他/她需要提供用户名 (security.user .name=admin)和密码(security.user.password=ENC(l2y+PuJeGIOMshbv+ddZgK8lOe2TRdt9YIuMwB5g5Ws=))在弹出窗口中。

现在我有一个java客户端,它在同一台机器上运行(将来它可能在远程位置运行),但具有不同的主机和端口,即127.0.0.1:8081尝试访问以编程方式位于 URI 之上,但无法这样做并最终得到响应代码 401。

401 是未经授权访问的响应代码,这是显而易见的。我的查询是是否可以以编程方式提供用户名和密码来访问上述 URI,即 https://127.0.0.2:8082/manager/metrics?或者防火墙是保护它的唯一方法?

我的java客户端代码:

    System.setProperty("javax.net.ssl.trustStore","D://SpringBoot/SpringWebAngularJS/truststore.ts");
    System.setProperty("javax.net.ssl.trustStorePassword","p@ssw0rd");
    try {
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){
            public boolean verify(String hostname,SSLSession sslSession) {
                return hostname.equals("127.0.0.2");
            }
        });
        URL obj = new URL("https://127.0.0.2:8082/manager/metrics");
        HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
        con.setRequestProperty( "Content-Type", "application/json" );
        con.setRequestProperty("Accept", "application/json");
        con.setRequestMethod("GET");
        con.setRequestProperty("User-Agent", "Mozilla/5.0");
        int responseCode = con.getResponseCode();
        System.err.println("GET Response Code :: " + responseCode); //Response code 401
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

最佳答案

根据所描述的浏览器行为,我假设端点受到基本身份验证的保护。

基本身份验证需要一个“Authorization” header ,其中包含以 base64 编码的以下形式的用户名和密码:“username:password”

如果您使用java 8,您可以使用java util包中提供的base64编码器,如下所示:

import java.util.Base64;

con.setRequestProperty("Authorization", Base64.getEncoder().encode("yourUsername:yourPassword".getBytes());

只是提供一些进一步的信息:

这与您的浏览器所做的完全相同。它发送请求并获取包含 header WWW-Authenticate: Basic 的 401 响应。因此浏览器知道身份验证方法是基本身份验证,并要求您提供用户名和密码,然后当浏览器第二次执行相同的请求时,该用户名和密码将通过 base64 编码并添加到授权 header 中。

关于java - 如何以编程方式验证 Spring Boot 端点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46296972/

相关文章:

javascript - 测试类无法读取consul配置

java - Android OpenGL ES 教程

mysql - Spring boot - h2和mysql的配置文件

java - 如何计算以字符串形式给出的数学表达式?

java - PowerMock-IllegalStateException : Must replay Class XXX to get configured expectation

java - Spring Boot JPA CrudRepository - 实体不附加到 persistencecontext

java - 在docker容器中运行时,HeapDumpOnOutOfMemoryError不转储堆

java - Spring 启动 Controller 404

java - Spring ehcache 未被使用

java - 置换函数的时间复杂度