Jersey客户端SSL相互身份验证

时间:2015-05-16 06:09:06

标签: java ssl jersey-client

我正在构建一个应用程序,我使用Jersey客户端从另一台服务器查询一些信息。我正在以下列方式执行呼叫:

....
result = ClientBuilder
    .newBuilder()
    .keyStore(KeyStoreUtils.loadKeyStore(KeyStoreUtils.TEST),
            KeyStoreUtils.getKeyStorePassword())
    .withConfig(new LoggingConfig()).build().target(serverUrl)
    .request()
    .post(Entity.entity(payload, request.getContentType()));
....    

密钥库是一个JKS密钥库,它只包含一个密钥对,应该用于SSL相互身份验证。 但是,尽管如此,我从服务器收到HTTP 401(未授权)错误。还有什么需要做的才能使SSL相互认证工作吗?

PS:我使用泽西岛版本2.14

1 个答案:

答案 0 :(得分:1)

我的想法是使用基于令牌的身份验证,可以通过HTTP头验证。我已经使用jersey 2.x API实现了相互客户端身份验证。

*证书采用PEM格式,并在客户端使用之前转换为Base64编码。 以下是使用基于证书的相互身份验证的Jersey Rest客户端示例 注意:CA证书。应在服务器密钥库配置 TEST.java

package your.package.here;

import org.glassfish.jersey.client.ClientConfig;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.File;
import java.io.FileWriter;
import java.nio.file.Files;
import java.nio.file.Paths;

public class TEST {
    public static final String codes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    public static String base64encodedCert;
    public static ClientBuilder clientBuilder;
    public static ClientConfig config;
    public static Client client;
    public static String res;

    public static void main(String[] args) {
        String urls = "http://YourDomain/URL/here/path";
        try {
            File certFile = new File("keystores/directory/Your_Cert_File.base64");
            if (!certFile.exists()) {
                FileWriter fileWriter = new FileWriter(certFile);
                fileWriter.write(base64Encode(new String(Files.readAllBytes(Paths.get("keystores/directory/Your_Cert_File.pem"))).getBytes()));
                fileWriter.close();
            }
            base64encodedCert = new String(Files.readAllBytes(Paths.get("keystores/directory/Your_Cert_File.base64")));
            clientBuilder = ClientBuilder.newBuilder();
            config = new ClientConfig();
            client = clientBuilder.withConfig(config).build();
            WebTarget target = client.target(urls);
            Response response = target.request().header("MY-CUSTOM-TOKEN", base64encodedCert).accept(MediaType.APPLICATION_XML).get();
            res = response.readEntity(String.class);
            response.close();
            System.out.println("res = " + res);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static String base64Encode(byte[] in) {
        StringBuilder out = new StringBuilder((in.length * 4) / 3);
        int b;
        for (int i = 0; i < in.length; i += 3) {
            b = (in[i] & 0xFC) >> 2;
            out.append(codes.charAt(b));
            b = (in[i] & 0x03) << 4;
            if (i + 1 < in.length) {
                b |= (in[i + 1] & 0xF0) >> 4;
                out.append(codes.charAt(b));
                b = (in[i + 1] & 0x0F) << 2;
                if (i + 2 < in.length) {
                    b |= (in[i + 2] & 0xC0) >> 6;
                    out.append(codes.charAt(b));
                    b = in[i + 2] & 0x3F;
                    out.append(codes.charAt(b));
                } else {
                    out.append(codes.charAt(b));
                    out.append('=');
                }
            } else {
                out.append(codes.charAt(b));
                out.append("==");
            }
        }
        return out.toString();
    }

}