Imagine um cenário onde você desenvolveu um Web Service e o publicou no servidor. Agora todos podem acessá-lo, mas você queria apenas que clientes especificamente registrados o acessassem, que apenas pessoas autorizadas possa acessar o Web Service. Uma maneira de fazer isso é usando o procedimento de autenticação em JAX-WS. Isto pode ser alcançado pelo cliente fornecendo um "username" e um "password", anexado no cabeçalho da solicitação SOAP e enviá-lo para o servidor.

O servidor, em seguida, analisa o documento SOAP e busca um "username" e "password" no cabeçalho. Em seguida, o servidor verifica se o "username" e "password" são válidos, comparando-os com um banco de dados (ou qualquer outro método preferencial) de usuários autorizados.

Supondo que o leitor deste artigo tenha conhecimentos básicos sobre SOAP e Web Services.

Etapa 1: Criar um programa simples em Java (Service)

Primeiro, vamos definir o serviço para ser implementado.

Listagem 1: HelloWorld.java

package com.devmedia.ws;
 
public interface HelloWorld {
   String getHelloWorldMessage();
}

A implementação é a seguinte:

Listagem 2: HelloWorldImpl.java

package com.devmedia.ws;
 
public class HelloWorldImpl  implements HelloWorld  {
    @Override
    public String getHelloWorldMessage(String myName){
        return("Hello "+myName+" to JAX WS world");
    }
} 

Passo 2: Modificar o serviço como Web Service

Modificar o serviço criado na seção anterior para o serviço da Web e também verificar a autenticação do usuário como mostra abaixo:

A visão de interface HelloWorld.java é a seguinte:

Listagem 3: HelloWorld.java updated

package com.devmedia.ws;
 
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
 
@WebService
@SOAPBinding(style = Style.RPC)
public interface HelloWorld {
 
    @WebMethod
    String getHelloWorldMessage();
 
} 

No Web Service do lado do servidor, se a solicitação parâmetros de cabeçalho via WebServiceContext.

Implementação revisada HelloWorldImpl.java é a seguinte:

Listagem 4: HelloWorldImpl.java updated

package com.devmedia.ws;
 
import java.util.List;
import java.util.Map;
 
import javax.annotation.Resource;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
 
@WebService(endpointInterface = "com.devmedia.ws.HelloWorld")
public class HelloWorldImpl implements HelloWorld {
    @Resource
    WebServiceContext wsctx;
 
    @Override
    public String getHelloWorldMessage() {
 
        MessageContext mctx = wsctx.getMessageContext();
 
        // Use the request headers to get the details
        Map http_headers =
            (Map) mctx.get(
            MessageContext.HTTP_REQUEST_HEADERS);
        List<String> userList = (List) http_headers.get("Username");
        List<String> passList = (List) http_headers.get("Password");
 
        String username = "";
        String password = "";
 
        if (userList != null) {
            username = userList.get(0);
        }
 
        if (passList != null) {
            password = passList.get(0);
 
        }
 
        if (username.equals("DevUser")
            &&
            password.equals("password")) {
            return "Hello "
                + username +
                " to world of Jax WS - Valid User!";
        } else {
            return " User No Valid!";
        }
    }
 
} 

Se você notar no código acima temos detalhes como nome de usuário e senha do cabeçalho da solicitação. Verifique se o nome de usuário é "DevUser" e se a senha é "password", em seguida retorna uma mensagem de autenticação bem-sucedida caso contrário retorno a mensagem de falha de autenticação.

Passo 3: Adding WS exposed code

Publicar a localidade Web Service criando o Endpoint publisher e expor o serviço no servidor.

Endpoint.publish("http://localhost:9000/ws/hello", new HelloWorldImpl());

Esta linha aqui começa uma leve http server endpoint que implanta seu web service e começa a aceitar solicitações de entrada.

O método a ser publicado usa dois parâmetros:

Endpoint URL String

Implementador do objeto, neste caso a classe de implementação HelloWorld, que é exposta como uma web service do endpoint identificado pela URL mencionada no parâmetro abaixo:

Listagem 5: HelloWorldPublisher.java


package com.devmedia.endpoint;
 
import javax.xml.ws.Endpoint;
import com.mrbool.ws.HelloWorldImpl;
 
public class HelloWorldPublisher {
 
   public static void main(String[] args){
       Endpoint.publish(
       "http://localhost:9000/ws/hello", new HelloWorldImpl());
       System.out.println(
       "\nWeb service published @ http://localhost:9000/ws/hello");
       System.out.println("You may call the web service now");
   }
}

Passo 4: Criar um Cliente Web Service

No código do cliente, coloque o "username" e "password" no cabeçalho de solicitação ao enviá-lo para a autenticação. Os comentários sobre cada passo no código explica o client code.

O arquivo do cliente, HelloWorldClient.java é o seguinte:

Listagem 6: HelloWorldClient.java


package com.devmedia.client;
 
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Service;
import javax.xml.ws.handler.MessageContext;
 
import com.devmedia.ws.HelloWorld;
 
public class HelloWorldClient {
    private static final String WS_URL =
            "http://localhost:9000/ws/hello?wsdl";
 
    public static void main(String[] args) throws Exception {
        URL url = new URL(WS_URL);
        QName qname = new QName(
            "http://ws.devmedia.com/",
            "HelloWorldImplService");
 
        Service service = Service.create(url, qname);
        HelloWorld hello = service.getPort(HelloWorld.class);
 
        // The BindingProvider interface provides
        //access to the protocol binding and
        // to the associated context objects
        //for request and response message processing.
        BindingProvider provider = (BindingProvider) hello;
        Map<String, Object> req_ctx = provider.getRequestContext();
        req_ctx.put(
        BindingProvider.ENDPOINT_ADDRESS_PROPERTY, WS_URL);
 
Map<String, List<String>> headers = new HashMap<String, List<String>>();
        headers.put("Username", Collections.singletonList("DevUser"));
        headers.put("Password",
            Collections.singletonList("password"));
        req_ctx.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
 
        System.out.println(hello.getHelloWorldMessage());
    }
}

Passo 5: Compile e execute

Compile os arquivos de serviço, edite-os e execute-os. Crie os arquivos em pacotes.

compileandrun.bat
dir /b /s *.java >> files.txt
javac @files.txt
java com.devmedia.endpoint.HelloWorldPublisher

Coloque os arquivos em pacotes no diretório com.devmedia.

A primeira linha do lote lista todos os arquivos java em subpastas e grava o caminho completo dos arquivos de "files.txt".

Segunda linha emite o comando compile para todos os arquivos java listados no arquivo "files.txt"

Terceira linha executa a classe HelloWorldPublisher.

Execute o arquivo de lote e a saída (System.out present na classe HelloWorldPublisher) como se segue:

Web service published @ http://localhost:9000/ws/hello

Agora você pode chamar o Web Service.

Passo 6: Test WS Client

Gravar um arquivo de lote para testar o client.

executeClient.bat
java com.devmedia.client.HelloWorldClient
PAUSE

Executar o executeClient.bat e a saída é a seguinte:

Hello DevUser to world of Jax WS - Valid User! 

Passo 7: Generate the WSDL

Testar o Web Service acessando o WSDL (Web Service Definition Language) gerador de documentos via URL http://localhost:9000/ws/hello?wsdl". Esta WSDL descreve em detalhes a API do Web Service. Como é language-neutral, client pode ser construído em qualquer linguagem de programação.

Conclusão

Neste artigo vimos como fornecer uma autenticação básica para um Web Service usando a linguagem de programação Java.

Artigo traduzido e originalmente publicado em: http://mrbool.com/web-service-authentication-using-java/28242