我正在尝试在Jdeveloper 11.1.1.7和weblogic 10.3的本地计算机中的客户端和服务器之间建立连接

我遵循以下博客中的步骤:

One size doesn't fit all: One-Way SSL with JAX-WS using JDeveloper 11gR1 and WLS 10.3.1

Gerard Davison's Blog: Security Policy Worked Example

所有步骤对我来说都很好。但是连接没有建立。

我有客户端和服务器的密钥库和自签名证书。我在客户端和服务器之间交换证书。因此,他们每个人在他的keystore文件中都有另一个人的证书作为受信任的证书。

从客户端,我尝试从Jdeveloper自动生成的port class调用服务器,其中已设置了所有内容,我所需要的只是填写用户名,密码,keyStore等的值。等等

但是我在客户端遇到以下异常。

java.lang.SecurityException: Can not find public key for alias: "serversidecert"
  at weblogic.wsee.security.util.CertUtils.getCertificate(CertUtils.java:106)
  at testClient.TestWSPortClient.getBSTCredentialProvider(TestWSPortClient.java:97)
  at testClient.TestWSPortClient.setPortCredentialProviderList(TestWSPortClient.java:71)
  at testClient.TestWSPortClient.main(TestWSPortClient.java:41)


注意1:我还无法访问服务器,此异常发生在客户端。

注2:该错误表明系统找不到指定别名的公钥。我知道公钥包含在证书中。因此,当将证书添加到受信任的keystore时,一切都应该顺利进行(如果我输入错了,请纠正我)。

-------------------------------编辑------------------ -------------------

我发现我在代码中做错了,因为该应用程序是从Jdeveloper中的Http Analyzer工作的。但是我没有看到代码中有什么问题。

以下是从Jdeveloper自动生成的端口类,并使用其填充的值:

注意3:ClientSideKeyStore.jks是客户端的keystore,它包含客户端的自签名证书和服务器证书(作为受信任的证书)

public class TestWSPortClient
{
  @WebServiceRef
  private static TestWSService testWSService;

    public static void main(String[] args) {
        try {
            testWSService = new TestWSService();
            TestWS testWS = testWSService.getTestWSPort();

            Map<String, Object> requestContext = ((BindingProvider) testWS).getRequestContext();
            setPortCredentialProviderList(requestContext);

             Add your code to call the desired methods.
            System.out.println("Client Side: "+testWS.sayhi("Testing Message"));

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    @Generated("Oracle JDeveloper")
    public static void setPortCredentialProviderList(Map<String, Object> requestContext) throws Exception {
        // TODO - Provide the required values
        String username = "weblogic";
        String password = "welcome1";
        String clientKeyStore = "C:\\Client_Server\\ClietSide\\ClientSideKeyStore.jks";
        String clientKeyStorePassword = "changeit";
        String clientKeyAlias = "clientsidecert";
        String clientKeyPassword = "changeit";
        String serverKeyStore = "C:\\Client_Server\\ClietSide\\ClientSideKeyStore.jks";
        String serverKeyStorePassword = "changeit";
        String serverKeyAlias ="serversidecert";
        List<CredentialProvider> credList = new ArrayList<CredentialProvider>();

        // Add the necessary credential providers to the list

        credList.add(getUNTCredentialProvider(username, password));

        credList.add(getBSTCredentialProvider(clientKeyStore, clientKeyStorePassword, clientKeyAlias, clientKeyPassword, serverKeyStore, serverKeyStorePassword, serverKeyAlias, requestContext));

        credList.add(getSAMLTrustCredentialProvider());

        requestContext.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credList);
    }

    @Generated("Oracle JDeveloper")
    public static CredentialProvider getSAMLTrustCredentialProvider() {
        return new SAMLTrustCredentialProvider();
    }

    @Generated("Oracle JDeveloper")
    public static CredentialProvider getUNTCredentialProvider(String username,
                                                              String password) {
        return new ClientUNTCredentialProvider(username.getBytes(), password.getBytes());
    }

    @Generated("Oracle JDeveloper")
    public static CredentialProvider getBSTCredentialProvider(String clientKeyStore,
                                                              String clientKeyStorePwd,
                                                              String clientKeyAlias,
                                                              String clientKeyPwd,
                                                              String serverKeyStore,
                                                              String serverKeyStorePwd,
                                                              String serverKeyAlias, Map<String, Object> requestContext) throws Exception {
        List serverCertList =
            CertUtils.getCertificate(serverKeyStore, serverKeyStorePwd, serverKeyAlias, "JKS");

        List clientCertList =
            CertUtils.getCertificate(clientKeyStore, clientKeyStorePwd, clientKeyAlias, "JKS");

        final X509Certificate serverCert =
            (serverCertList != null && serverCertList.size() > 0) ? (X509Certificate) serverCertList.get(0) : null;
        final X509Certificate clientCert =
            (clientCertList != null && clientCertList.size() > 0) ? (X509Certificate) clientCertList.get(0) : null;

        requestContext.put(WSSecurityContext.TRUST_MANAGER, new TrustManager()
       {
          public boolean certificateCallback(X509Certificate[] chain,
                                             int validateErr)
          {
             boolean result = (chain != null && chain.length > 0)
                              && (chain[0].equals(serverCert) || chain[0].equals(clientCert));
             return result;
          }
       });

        return new ClientBSTCredentialProvider(clientKeyStore, clientKeyStorePwd, clientKeyAlias, clientKeyPwd, "JKS", serverCert);
    }
}

最佳答案

验证文件C:\\Client_Server\\ClietSide\\ClientSideKeyStore.jks是否可由客户端读取,以及它是否确实包含别名为serversidecert的证书:

keytool -list -v -keystore C:\\Client_Server\\ClietSide\\ClientSideKeyStore.jks -alias serversidecert


也就是说,您确定客户端证书ClientSideKeyStore是此处所需的服务器证书吗?

Weblogic doc上,(通常)在没有别名参数的情况下(通常)对服务器端证书进行不同的初始化。也许您也可以尝试以下方法:

X509Certificate serverCertInit = (X509Certificate) CertUtils.getCertificate(serverKeyStore);

10-04 13:15