Java 带灰熊和球衣的SSL

Java 带灰熊和球衣的SSL,java,rest,ssl,jersey,grizzly,Java,Rest,Ssl,Jersey,Grizzly,我试图让grizzly使用SSL加密,并且仍然可以很好地使用Jersey。我浏览了整个互联网,发现了各种不同的尝试,比如Grizzly和Jersey。似乎有不同的方法来实现它,这取决于您使用的版本以及您决定如何实现它。我还没有找到任何例子来使用我的代码 以下是我如何启动服务器: static HttpServer startSecureServer() throws IOException{ ResourceConfig rc=new PackagesResourceConfig

我试图让grizzly使用SSL加密,并且仍然可以很好地使用Jersey。我浏览了整个互联网,发现了各种不同的尝试,比如Grizzly和Jersey。似乎有不同的方法来实现它,这取决于您使用的版本以及您决定如何实现它。我还没有找到任何例子来使用我的代码

以下是我如何启动服务器:

static HttpServer startSecureServer() throws IOException{
        ResourceConfig rc=new PackagesResourceConfig("server.grizzlyresources");
        SSLContextConfigurator sslCon=new SSLContextConfigurator();

        sslCon.setKeyStoreFile(ConfigLoader.getKeystoreLocation()); // contains server keypair
        sslCon.setKeyStorePass(ConfigLoader.getKeystorePassword());

        System.out.println("Starting server on port "+ConfigLoader.getHttpsServerPort());
        HttpServer secure=GrizzlyServerFactory.createHttpServer(BASE_URI_SECURED, rc);
        secure.stop();

        HashSet<NetworkListener> lists=new HashSet<NetworkListener>(secure.getListeners());
        for (NetworkListener listener : lists){
            listener.setSecure(true);
            SSLEngineConfigurator ssle=new SSLEngineConfigurator(sslCon);
            listener.setSSLEngineConfig(ssle);
            secure.addListener(listener);
            System.out.println(listener);
        }

        secure.start();
        return secure;
}

private static URI getBaseURISecured(){
    return UriBuilder.fromUri("https://0.0.0.0/").port(ConfigLoader.getHttpsServerPort()).build();
}

private static final URI BASE_URI_SECURED = getBaseURISecured();
我用的是灰熊2.2.1和泽西1.12


非常感谢

IMO您可以使用不同的工厂方法来初始化安全的Grizzly HttpServer:

HttpServer secure = GrizzlyServerFactory.createHttpServer(BASE_URI_SECURED,
                        ContainerFactory.createContainer(HttpHandler.class, rc),
                        true,
                        new SSLEngineConfigurator(sslCon));
如果像这样初始化服务器,则无需停止并重新配置


希望这会有所帮助。

我有一个使用Grizzly 2.3.3的好例子:

以下代码适用于Grizzly 2.3.7,我正在使用Jersey 1.18-这包括用于SSL客户端身份验证的代码-如果您没有密钥库,此功能将被忽略

/**
 * create a Server based on an url and possibly a ResourceConfig
 * 
 * @param url
 * @param rc
 * @param secure
 *          - true if SSL should be used
 * @param contextPath 
 * @return
 * @throws Exception
 */
public HttpServer createHttpServer(String url, ResourceConfig rc,
        boolean secure, String contextPath) throws Exception {
    // HttpServer result = GrizzlyServerFactory.createHttpServer(url, rc);
    // http://grepcode.com/file/repo1.maven.org/maven2/com.sun.jersey/jersey-grizzly2/1.6/com/sun/jersey/api/container/grizzly2/GrizzlyServerFactory.java#GrizzlyServerFactory.createHttpServer%28java.net.URI%2Ccom.sun.jersey.api.container.grizzly2.ResourceConfig%29
    HttpServer result = new HttpServer();
    final NetworkListener listener = new NetworkListener("grizzly",
            settings.getHost(), settings.getPort());
    result.addListener(listener);
    // do we need SSL?
    if (secure) {
        listener.setSecure(secure);
        SSLEngineConfigurator sslEngineConfigurator = createSSLConfig(true);
        listener.setSSLEngineConfig(sslEngineConfigurator);
    }
    // Map the path to the processor.
    final ServerConfiguration config = result.getServerConfiguration();
    final HttpHandler handler = ContainerFactory.createContainer(
            HttpHandler.class, rc);
    config.addHttpHandler(handler, contextPath);
    return result;
}

  /**
 * create SSL Configuration
 * 
 * @param isServer
 *          true if this is for the server
 * @return
 * @throws Exception
 */
private SSLEngineConfigurator createSSLConfig(boolean isServer)
        throws Exception {
    final SSLContextConfigurator sslContextConfigurator = new SSLContextConfigurator();
    // override system properties
    final File cacerts = getStoreFile("server truststore",
            "truststore_server.jks");
    if (cacerts != null) {
        sslContextConfigurator.setTrustStoreFile(cacerts.getAbsolutePath());
        sslContextConfigurator.setTrustStorePass(TRUSTSTORE_PASSWORD);
    }

    // override system properties
    final File keystore = getStoreFile("server keystore", "keystore_server.jks");
    if (keystore != null) {
        sslContextConfigurator.setKeyStoreFile(keystore.getAbsolutePath());
        sslContextConfigurator.setKeyStorePass(TRUSTSTORE_PASSWORD);
    }

    //
    boolean clientMode = false;
    // force client Authentication ...
    boolean needClientAuth = settings.isNeedClientAuth();
    boolean wantClientAuth = settings.isWantClientAuth();
    SSLEngineConfigurator result = new SSLEngineConfigurator(
            sslContextConfigurator.createSSLContext(), clientMode, needClientAuth,
            wantClientAuth);
    return result;
}

很抱歉花了这么长时间在这里发布。Alexey的回答让我找到了可行的解决方案,这很像Wolfgang Fahl的代码。以下是我最终得到的结果:

static HttpServer startSecureServer() throws IOException
{
    System.out.println("Starting server on port " + ConfigLoader.getHttpsServerPort());
    ResourceConfig rc = new PackagesResourceConfig("com.kinpoint.server.grizzlyresources");

    SSLContextConfigurator sslCon = new SSLContextConfigurator();

    sslCon.setKeyStoreFile(ConfigLoader.getKeystoreLocation()); // contains server keypair
    sslCon.setKeyStorePass(ConfigLoader.getKeystorePassword());

    HttpHandler hand = ContainerFactory.createContainer(HttpHandler.class, rc);

    HttpServer secure = GrizzlyServerFactory.createHttpServer(BASE_URI_SECURED, hand, true,
            new SSLEngineConfigurator(sslCon, false, false, false));

    return secure;
}

SSLengineConfigulator中的第二个参数告诉它不要使用客户端模式。这就是把我搞砸的原因。谢谢你的帮助。

谢谢你的回复!这不起作用,但它让我走上了一条搜索路径,我希望这条路径能找到解决方案。服务器现在安全启动,但当我尝试使用
openssl s_client-connect localhost:9999时,它会在握手时死掉。我想我可能只需要将所有内容迁移到最新版本的Jersey上,据我所知,它与Jersey 1.12完全不同。如果我弄明白了,我会发回的。你可以启用SSL调试:“-Djavax.net.debug=all”,看看为什么握手会失败这么多!调试信息显示它正在尝试验证客户端(我不希望它这样做)。通过查看grizzly文档,我发现在构造SSLengineConfigulator时,我可以传入布尔值,告诉它不要对客户端进行身份验证。成功了!我想他提到了这个:新的SSLengineConfigulator(sslContextConfigurator)。setNeedClientAuth(false)不要忘记禁用客户端模式,看看这个StackOverflow问题:这非常有用。我注意到,当我使用伪造的凭据(密钥库位置/密码)启动服务器时,我没有收到任何异常,但该服务不可用。您的ConfigLoader是否进行了一些验证,或者您是否找到了另一种捕获错误的方法?
static HttpServer startSecureServer() throws IOException
{
    System.out.println("Starting server on port " + ConfigLoader.getHttpsServerPort());
    ResourceConfig rc = new PackagesResourceConfig("com.kinpoint.server.grizzlyresources");

    SSLContextConfigurator sslCon = new SSLContextConfigurator();

    sslCon.setKeyStoreFile(ConfigLoader.getKeystoreLocation()); // contains server keypair
    sslCon.setKeyStorePass(ConfigLoader.getKeystorePassword());

    HttpHandler hand = ContainerFactory.createContainer(HttpHandler.class, rc);

    HttpServer secure = GrizzlyServerFactory.createHttpServer(BASE_URI_SECURED, hand, true,
            new SSLEngineConfigurator(sslCon, false, false, false));

    return secure;
}