Search code examples
soapjax-wsbasic-authentication

JAX-WS: SOAP: implement server Basic Authentification with JRE only


I've already implemented a JAX-WS with Java 8 runtime. Now I need to add the basic authentication support at both client and server sides:

  1. I do know how to manually add the 'Authorization: Basic ...' header at the client side, but I want the client to add it when it receives the 401 response from the server only;
  2. I do NOT know how to make the server to check this header value and return the 401 response if this header is missing or the credential check is not passed;
  3. I need the implementation based on JRE only (no Tomcat, Weblogic, Glassfish etc.).

Solution

  • Although you might already solved your problem I want to provide a sample implementation if someone else have some use for it.

    Server:

    javax.xml.ws.Endpoint serverEndpoint = Endpoint.create(new MyService());
    
    com.sun.net.httpserver.HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
    
    com.sun.net.httpserver.HttpContext httpContext = server.createContext("/myservice");
    
    server.start();
    
    AuthenticatorServer authenticatorServer = new AuthenticatorServer("myRealm", "myName", "myPwd");
    
    httpContext.setAuthenticator(authenticatorServer);  
    
    serverEndpoint.publish(httpContext);
    

    Where AuthenticatorServer is:

    private static class AuthenticatorServer extends com.sun.net.httpserver.BasicAuthenticator {
    
        private final String user;
        private final String pwd;
    
        public AuthenticatorServer(String realm, String user, String pwd) {
            super(realm);
            this.user = user;
            this.pwd = pwd;
        }
    
        @Override
        public boolean checkCredentials(String userNameInput, String passwordInput) {
    
            return StringUtils.equals(user, userNameInput) && StringUtils.equals(pwd, passwordInput);
    
        }
    
    }
    

    And on the Client side:

    AuthenticatorClient authenticatorClient = new AuthenticatorClient("myName", "myPwd");
    
    Authenticator.setDefault(authenticatorClient);
    
    javax.xml.namespace.QName qName = new QName(namespaceURI, WS_SERVICE_NAME);
    java.net.URL wsdlAddress = new URL(namespaceURI + WS_SERVICE_NAME + "?wsdl");
    
    MyService service =(Service.create(wsdlAddress, qName)).getPort(MyService.class);
    

    Where AuthenticatorClient is:

    private static class AuthenticatorClient extends java.net.Authenticator {
    
        private final String user;
        private final String pwd;
    
        public AuthenticatorClient(String user, String pwd) {
            this.user = user;
            this.pwd = pwd;
        }
    
        @Override
        public PasswordAuthentication getPasswordAuthentication() {
            return (new PasswordAuthentication(user, pwd == null ? null : pwd.toCharArray()));
        }
    
    }