grails-RestClientBuilder

grails-RestClientBuilder,rest,grails,curl,Rest,Grails,Curl,我正在使用当前版本的rest客户端生成器插件。我通过curl测试了uri: curl --user username:password https://localhost:8085/rest/api/latest/plan.json?os_authType=basic 我得到了预期的json作为回报。当我尝试使用如下插件将其转换为grails时: RestBuilder rb = new RestBuilder() def response = rb.get("https://loca

我正在使用当前版本的rest客户端生成器插件。我通过curl测试了uri:

curl --user username:password https://localhost:8085/rest/api/latest/plan.json?os_authType=basic
我得到了预期的json作为回报。当我尝试使用如下插件将其转换为grails时:

RestBuilder rb = new RestBuilder()
    def response = rb.get("https://localhost:8085/rest/api/latest/plan.json?os_authType=basic"){     
            auth 'username', 'password'
        }

response.json instanceof JSONObject
我得到这个错误:

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
为什么它在curl中工作而不与插件一起工作?我怎样才能让它工作


谢谢

您需要将根证书添加到受信任证书的存储中


将证书作为受信任的证书导入 在授予签名代码读取指定文件的权限之前,需要将Susan的证书作为受信任证书导入密钥库

假设你收到了苏珊的来信

  • 签名的JAR文件
    scont.JAR
    ,其中包含
    Count.class
    文件,以及
  • 文件
    Example.cer
    ,其中包含与用于签署JAR文件的私钥相对应的公钥的公钥证书
即使您创建了这些文件,但它们实际上并没有被传输到任何地方,您也可以模拟成为除创建者和发送者Susan之外的其他人。假装你现在是雷。作为Ray,您将创建一个名为
exampleraystore
的密钥库,并使用它将证书导入别名为
susan
的条目中

每当您使用指定尚未存在的密钥库的
keytool
命令时,就会创建密钥库。因此,我们可以创建
exampleraystore
并通过单个
keytool
命令导入证书。在命令窗口中执行以下操作

  • 转到包含公钥证书文件的目录
    Example.cer
    。(实际上您应该已经在那里了,因为本课程假设您始终停留在一个目录中。)
  • 在一行中键入以下命令:

    keytool-导入-别名susan -文件Example.cer-密钥库exampleraystore

  • 由于密钥库尚不存在,因此将创建密钥库,并提示您输入密钥库密码;键入您想要的密码

    keytool
    命令将打印出证书信息,并要求您进行验证,例如,将显示的证书指纹与从另一个(受信任的)信息源获得的指纹进行比较。(每个指纹都是一个相对较短的数字,可以唯一、可靠地识别证书。)例如,在现实世界中,你可以打电话给Susan,问她指纹应该是什么。她可以获得通过执行命令创建的
    Example.cer
    文件的指纹

    keytool-printcert-file Example.cer


    如果她看到的指纹与通过
    keytool
    向您报告的指纹相同,则证书在传输过程中未被修改。在这种情况下,您可以让
    keytool
    继续在密钥库中放置受信任的证书条目。该条目包含文件
    Example.cer
    中的公钥证书数据,并被分配了别名
    susan

    您只需禁用RestBuilder的SSL检查即可

    请参见代码示例:

    static Scheme disableSSLCheck() {
    
            def sslContext = SSLContext.getInstance("SSL")
            sslContext.init(null, [new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] certs, String authType) {}
    
                public void checkServerTrusted(X509Certificate[] certs, String authType) {}
    
                @Override
                X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0]
                }
            }] as TrustManager[], new SecureRandom())
            def sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
            def httpsScheme = new Scheme("https", sf, 443)
            httpsScheme
    
        }
    
    并将此方案注册到RestClient:

    Scheme httpsScheme = disableSSLCheck()
    restClient.client.connectionManager.schemeRegistry.register(httpsScheme)
    

    Mb太晚了,但请看这里。

    在我的集成测试中,我确实将它作为单独的方法

     def static disableSSLCheck() {
        def nullTrustManager = [
                checkClientTrusted: { chain, authType -> },
                checkServerTrusted: { chain, authType -> },
                getAcceptedIssuers: { null }
        ]
    
        def nullHostnameVerifier = [
                verify: { hostname, session -> true }
        ]
    
        SSLContext sc = SSLContext.getInstance("SSL")
        sc.init(null, [nullTrustManager as X509TrustManager] as TrustManager[], null)
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory())
        HttpsURLConnection.setDefaultHostnameVerifier(nullHostnameVerifier as HostnameVerifier)
    }
    
    然后就

    void "test authentication"(){
        given:
        String url = "j_spring_security_check"
        MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>()
        form.add("grant_type", "password")
        form.add("j_username", "vadim@ondeviceresearch.com")
        form.add("j_password", "notSecure")
        form.add("_spring_security_remember_me", "true")
        //TODO SET username and pass
        //todo get token back
        disableSSLCheck()
        when:
        RestResponse response = rest.post(host + url){
            accept("application/json")
            contentType("application/x-www-form-urlencoded")
            body(form)
        }
        response
        then:
        response.status == 200
    }
    
    void“测试验证”(){
    鉴于:
    String url=“j_spring_security_check”
    MultiValueMap form=新链接的MultiValueMap()
    表格.添加(“授权类型”、“密码”)
    表格。添加(“j_用户名”vadim@ondeviceresearch.com")
    表格。添加(“j_密码”、“不安全”)
    添加(“\u spring\u security\u memory\u me”,“true”)
    //TODO设置用户名和密码
    //要取回代币吗
    disableSSLCheck()
    什么时候:
    resresponse response=rest.post(主机+url){
    接受(“应用程序/json”)
    contentType(“application/x-www-form-urlencoded”)
    正文(表格)
    }
    响应
    然后:
    response.status==200
    }
    
    谁知道Http而不是https?