jetty with resteasy http/https

import com.google.inject.Inject;
import com.google.inject.Injector;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.security.SecurityHandler;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.security.authentication.DigestAuthenticator;
import org.eclipse.jetty.server.*;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.util.security.Credential;
import org.eclipse.jetty.util.security.Password;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher;

import javax.management.*;
import java.io.IOException;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.net.URISyntaxException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.stream.Stream;

import static java.lang.System.getProperty;

public class OmsDBRestful implements OmsDBRestfulMBean {
    private static final String KEY_MANAGER_PASSWORD = "OBF:1v2j1uum1xtv1zej1zer1xtn1uvk1v1v";
    //    private static final String KEY_MANAGER_PASSWORD = "password";
    private static final String KEY_STORE_PASSWORD = "OBF:1v2j1uum1xtv1zej1zer1xtn1uvk1v1v";
    private static final String KEY_STORE_PATH = "/oms-db-restful-auth-keystore.prd";
    public static final String JKS = "JKS";
    //    private static final String KEY_STORE_PASSWORD = "password";
    private final int port;
    private final int sslPort;
    private final ApplicationEvent eventLogger;
    private Server server;
    private final boolean authEnabled;
    private Status status;

    public static void main(String[] args) throws Exception {
        Injector injector = GuiceContext.instance().injector();
        OmsDBRestful process = injector.getInstance(OmsDBRestful.class);
        registerMBean(process);
        process.start().join();
    }


    @Inject
    public OmsDBRestful(OmsDBRestfulConfig config, ApplicationEvent eventLogger) {
        this.eventLogger = eventLogger;
        this.port = config.restfulPort();
        this.sslPort = config.restfulSslPort();
        this.authEnabled = config.isAuthEnabled();
        this.status = Status.STARTING;
    }

    public OmsDBRestful start() throws Exception {
        server = new Server();
        HandlerCollection handlers = new HandlerCollection();
        if (authEnabled) {
            handlers.setHandlers(new Handler[]{servletContextHandlerWithAuth(), servletContextHandler()});
            server.addConnector(httpsConnector());
        } else {
            handlers.setHandlers(new Handler[]{servletContextHandler()});
        }

        server.setHandler(handlers);
        server.addConnector(httpConnector());

        server.start();
        eventLogger.processStarted();
        this.status = Status.UP;
        return this;
    }

    private Connector httpConnector() {
        ServerConnector http = new ServerConnector(server,
                new HttpConnectionFactory());
        http.setPort(port);
        http.setIdleTimeout(30000);
        return http;
    }

    private ServerConnector httpsConnector() throws URISyntaxException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException {
        HttpConfiguration httpsConfig = new HttpConfiguration();
        httpsConfig.setSecureScheme("https");
        httpsConfig.setSecurePort(sslPort);
        httpsConfig.setOutputBufferSize(32768);
        httpsConfig.addCustomizer(new SecureRequestCustomizer());

        ServerConnector https = new ServerConnector(server,
                new SslConnectionFactory(sslContextFactory(), HttpVersion.HTTP_1_1.asString()),
                new HttpConnectionFactory(httpsConfig));
        https.setPort(sslPort);
        https.setIdleTimeout(500000);
        return https;
    }

    private SslContextFactory sslContextFactory() throws URISyntaxException, KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
        KeyStore keyStore = KeyStore.getInstance(JKS);

        Password realPassword = Password.getPassword("org.eclipse.jetty.ssl.password", KEY_STORE_PASSWORD, null);
        InputStream keyStoreStream = getClass().getResourceAsStream(KEY_STORE_PATH);
        if (keyStoreStream == null) {
            throw new IllegalArgumentException("Can't find keystore: " + KEY_STORE_PATH);
        }
        keyStore.load(keyStoreStream, realPassword.toString().toCharArray());

        SslContextFactory sslContextFactory = new SslContextFactory();
        sslContextFactory.setKeyStore(keyStore);
        sslContextFactory.setKeyManagerPassword(KEY_MANAGER_PASSWORD);
        return sslContextFactory;
    }

    private RequestLogHandler createRequestLogHandler(String logFilePrefix) {
        AsyncNCSARequestLog requestLog = new AsyncNCSARequestLog();
        requestLog.setFilename(getProperty("app.logpath", "local") + "/" + logFilePrefix + "access-yyyy_MM_dd.log");
        requestLog.setLogDateFormat("yyyy-MM-dd HH:mm:ss,sss");
        requestLog.setAppend(true);
%A        requestLog.setExtended(false);
        requestLog.setLogTimeZone("UTC");
        requestLog.setRetainDays(10);
        RequestLogHandler requestLogHandler = new RequestLogHandler();
        requestLogHandler.setRequestLog(requestLog);
        return requestLogHandler;
    }

    private ServletContextHandler servletContextHandler() {
        final ServletHolder restEasyServletHolder = new ServletHolder(new HttpServletDispatcher());
        restEasyServletHolder.setInitOrder(1);
        restEasyServletHolder.setInitParameter("javax.ws.rs.Application", OmsDBRestApplication.class.getCanonicalName());

        final ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
        contextHandler.setContextPath("/oms-db");
        contextHandler.addServlet(restEasyServletHolder, "/*");
        contextHandler.setHandler(createRequestLogHandler(""));
        return contextHandler;
    }

    private ServletContextHandler servletContextHandlerWithAuth() {
        final ServletHolder restEasyServletHolder = new ServletHolder(new HttpServletDispatcher());
        restEasyServletHolder.setInitOrder(2);
        restEasyServletHolder.setInitParameter("javax.ws.rs.Application", OmsDBRestApplication.class.getCanonicalName());

        final ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
        contextHandler.setContextPath("/v1/oms-db");
        contextHandler.addServlet(restEasyServletHolder, "/*");
        contextHandler.setHandler(createRequestLogHandler("secured-"));

        contextHandler.setSecurityHandler(
                basicAuth(
                        new UserCredential("support", "support", "OMS Database Restful site"),
                        new UserCredential("COG", "ClientOrderGateway", "OMS Database Restful site")
                )
        );

        return contextHandler;
    }

    public void join() throws InterruptedException {
        server.join();
    }

    public void stop() throws Exception {
        server.stop();
        status = Status.SHUTDOWN;
    }

    private static SecurityHandler basicAuth(UserCredential... userCredentials) {

        HashLoginService l = new HashLoginService();
        Stream.of(userCredentials).forEach(userCredential -> {
            l.putUser(userCredential.userName, Credential.getCredential(userCredential.password), new String[]{"user"});
            l.setName(userCredential.realm);
        });

        Constraint constraint = new Constraint();
        constraint.setName(Constraint.__BASIC_AUTH);
        constraint.setRoles(new String[]{"user"});
        constraint.setAuthenticate(true);

        ConstraintMapping cm = new ConstraintMapping();
        cm.setConstraint(constraint);
        cm.setPathSpec("/*");

        ConstraintSecurityHandler csh = new ConstraintSecurityHandler();
        csh.setAuthenticator(new BasicAuthenticator());
        csh.setRealmName("myrealm");
        csh.addConstraintMapping(cm);
        csh.setLoginService(l);

        return csh;
    }

    private static SecurityHandler digestAuth(UserCredential... userCredentials) {
        HashLoginService l = new HashLoginService();
        Stream.of(userCredentials).forEach(userCredential -> {
            l.putUser(userCredential.userName, Credential.getCredential(userCredential.password), new String[]{"user"});
            l.setName(userCredential.realm);
        });

        Constraint constraint = new Constraint();
        constraint.setName(Constraint.__DIGEST_AUTH);
        constraint.setRoles(new String[]{"user"});
        constraint.setAuthenticate(true);

        ConstraintMapping cm = new ConstraintMapping();
        cm.setConstraint(constraint);
        cm.setPathSpec("/*");

        ConstraintSecurityHandler csh = new ConstraintSecurityHandler();
        csh.setAuthenticator(new DigestAuthenticator());
        csh.setRealmName("myrealm");
        csh.addConstraintMapping(cm);
        csh.setLoginService(l);

        return csh;
    }

    @Override
    public boolean isUp() {
        return getStatus().equals(Status.UP.name());
    }

    @Override
    public String getStatus() {
        return Status.UP.name();
    }

    private static class UserCredential {
        private String userName;
        private String password;
        private String realm;

        public UserCredential(String userName, String password, String realm) {
            this.userName = userName;
            this.password = password;
            this.realm = realm;
        }

        public String userName() {
            return userName;
        }

        public String password() {
            return password;
        }

        public String realm() {
            return realm;
        }
    }

    private static void registerMBean(OmsDBRestful process) throws MalformedObjectNameException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException {
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        ObjectName name = new ObjectName("com.hsbc.efx.orders:type=OmsDBRestful");
        mbs.registerMBean(process, name);
    }
}

猜你喜欢

转载自seafront12.iteye.com/blog/2330050