Veja o porque nos comentários.
Em breve irei postar um comentário ou um novo post com a solução correta.
Estou começando a estudar WebServices e uma de minhas primeiras necessidades é implementar um WebService que seja acessado apenas por 'pessoas' autorizadas.
Dessa forma, nesse post irei explicar como se implementa e acessa um WebService utilizando segurança na camada HTTP com o JBoss 5 e Axis.
1) Crie um novo EJB Project: File, New, Project, EJB, EJB Project.
2) O segundo passo é codificar uma Interface que extende de java.rmi.Remote:
package br.com.hello;
import java.rmi.Remote;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
@WebService
@SOAPBinding(style = Style.DOCUMENT)
public interface HelloWS extends Remote {
public String hello();
}
3) Codificar uma classe que implementa a Interface:
package br.com.hello;
import javax.annotation.Resource;
import javax.annotation.security.RolesAllowed;
import javax.ejb.Remote;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.jws.WebService;
import org.jboss.ejb3.annotation.SecurityDomain;
import org.jboss.wsf.spi.annotation.WebContext;
@Stateless
@WebService(endpointInterface = "br.com.hello.HelloWS")
@Remote(HelloWS.class)
@SecurityDomain("JBossWS")
@RolesAllowed("admin")
@WebContext(contextRoot="/hello", urlPattern="/*", authMethod="BASIC", transportGuarantee="NONE", secureWSDLAccess=false)
public class HelloBean {
@Resource
SessionContext ctx;
public String hello() {
String user = String.valueOf(ctx.getCallerPrincipal());
return "Hello " + user + "!";
}
}
Observações:@Stateless: Define o EJB sendo sem estado, ou seja, será um EJB que não irá manter o seu estado para cada invocação de um método;
@WebService(endpointInterface = "com.roassunca.hellows.HelloWS"): Especifica a interface que define os métodos do WebService;
@Remote(HelloWS.class);
@SecurityDomain("JBossWS"):Define qual Realm o EJB deve utilizar. Nesse caso estou utilizando um já definido na configuração Default do JBoss (veja o arquivo
@RolesAllowed("admin"):Define quais roles poderão acessar o WebService;
@WebContext(contextRoot="/hello", urlPattern="/*", authMethod="BASIC", transportGuarantee="NONE", secureWSDLAccess=false):Define a segurança do EJB na camada Web, utilizando como autenticação o método BASIC.
@Resource
SessionContext ctx;
Serve para injetar o SessionContext, para que possa ser utilizado para buscar o nome do usuário.
4) Compile e crie um .jar
5) Copie o .jar para jboss-dir/server/default/deploy
6) Inicie o JBoss
7) Copie o ultimo arquivo .wsdl gerado em jboss-dir/server/default/data/wsdl/hello.jar para a pasta do seu projeto no Eclipse
8) Clique com o mouse botão direito sobre o arquivo .wsdl no Eclipse e selecione New, Other, WebServices, Web Service Client, Next
9) Client type: Java Proxy
No lado direito da tela, deixe apenas a opção Develop Client.
Certifique-se de que nas configurações estejam selecionados Server: JBoss, Web service runtime: Apache Axis, Client project: o projeto onde será criado os fontes
Clique em Next
10) Abra o fonte gerado br.com.hello.HelloWSBindingStub
11) No metodo protected org.apache.axis.client.Call createCall(), após a linha onde é chamado super._createCall(); defina o nome de usuário e senha:
_call.setUsername("admin");
_call.setPassword("admin");
12) Não se esqueca de definir no arquivo jboss-dir/server/default/conf/props/jbossws-roles.properties o role do usuário admin:admin=admin
e no arquivo jboss-dir/server/default/conf/props/jbossws-users.properties a senha do usuário admin:
admin=admin
13) Implemente um método main em HelloWSProxy:
public static void main(String[] args) throws Exception {
System.out.println( new HelloWSProxy().hello() );
}
14) Caso o seu projeto (a implementação do WebService) precise incluir alguns arquivos .jar (como bibliotecas), para fazer o deploy, crie um arquivo .ear, contendo o .jar que você acabou de criar e uma pasta lib com todos os outros .jars necessários.
Caiu a ficha que essa solução não funciona por um simples motivo: por ser um EJB Stateless o container EJB poderá instanciar apenas um EJB para toda chamada ao WebService.
ResponderExcluirDessa forma, ao invocar ctx.getCallerPrincipal() você sempre irá obter o mesmo usuário.