Ok, so i got the server working basically (i think) but when
calling it
i get the following exception at the client:
AxisFault
faultCode:
{http://schemas.xmlsoap.org/soap/envelope/}Server.generalException
faultSubcode:
faultString: WSDoAllReceiver: Request does not contain required
Security header
Thats the client code so far:
try {
binding = new
al.JCT.service.JCTServiceLocator().getJCTSession();
Stub axisPort = (Stub)binding;
axisPort._setProperty(UsernameToken.PASSWORD_TYPE,
WSConstants.PASSWORD_DIGEST);
axisPort._setProperty(WSHandlerConstants.USER, "wss4j");
axisPort._setProperty(WSHandlerConstants.PW_CALLBACK_REF, new
PWCallback());
}
catch (javax.xml.rpc.ServiceException jre) {
jre.printStackTrace();
return;
}
try {
al.JCT.service.Job[] value = null;
String ids[] = {"1218"};
value = binding.getJobStatus("rudi", "qw", null, ids);
if (value != null) {
for (int i=0; i < value.length; i++) {
System.out.println(value[i].getId() + " - " +
value[i].getName() + " - " + value[i].getPe());
System.out.println(value[i].getReservations());
System.out.println(value[i].getOutputPaths()[0].getPath());
}
}
binding.submitJob(null, null, null);
}
catch (java.rmi.RemoteException re) {
re.printStackTrace();
return;
}
Any ideas on this one?
Thx!
Michael
you can extract all the security info by looking at the
Vector stored
as a property in the MessageContext:
Vector resultHandlers =
(Vector)MessageContext.getCurrentContext().getProperty(WSHandlerConstants.RECV_RESULTS);
this vector contains, as far as i can tell, everything you
could want
to know.
or you can extract the username from the message itself -
ArrayList actorList = new ArrayList();
actorList.add("actor value for my UsernameToken entry");
Message request =
MessageContext.getCurrentContext().getRequestMessage();
SOAPEnvelope envelope = (SOAPEnvelope)request.getSOAPEnvelope();
Vector headers = envelope.getHeadersByActor(actorList);
SOAPHeaderElement header = (SOAPHeaderElement)headers.get(0);
you can then extract the actual username by walking the DOM
tree to
the node which contains the username
MessageElement usernameTokenElement =
header.getChildElement(USERNAME_TOKEN_QNAME);
MessageElement usernameElement =
usernameTokenElement.getChildElement(USERNAME_QNAME);
String username = usernameElement.getValue();
(you'll also need these)
static final QName USERNAME_TOKEN_QNAME = new
QName(WSConstants.WSSE_NS, WSConstants.USERNAME_TOKEN_LN);
static final QName USERNAME_QNAME = new
QName(WSConstants.WSSE_NS,
WSConstants.USERNAME_LN);
in my app i have a handler which i put in the request chain
right
after the WSDoAllReceiver which extracts the username using
the above
code, does an LDAP lookup of the user to gather roles, and then
creates an app-specific user object which it stores it as a
properly
in the MessageContext where anyone in the handling chain can
then
extract it via getProperty().
hth.
......................ron.
Michael Rudolf wrote:
Thanks a lot for the detailed description! I think this will
work
fine for me. One more question about this though: Can i read
the
username inside the web service? Or is there any way of getting
information like the group a user belongs to inside the web
service
to read it there? It sounds like the Service does get any of
this
info since the authentication is completely transparent to the
service itself.
Thanks.
Michael
by "Web Services are made out of Session EJBs" you mean you
have
Session EJBs that expose a SOAP-over-HTTP interface? WSS4J
uses 2
handlers, one client-side and one server-side (WSDoAllSender
(client) and WSDoAllReceiver (server)) which plug into the
handler
chain supported by Axis to "intercept" the request on its
way to the
server. WSDoAllSender adds a WSSecurity header to the SOAP
message
on send (configured using a properties file).
WSDoAllReceiver then
processes the incoming message, validates whatever it's
configured
to validate and then passes the request on to your
handlers/service
(or rejects the message if it does not validate properly).
to add
UsernameTokens to a request and process them on the server
requires
a CallbackHandler on the client side which can provide the
password
for a user. this is then processed into a UsernameToken,
included
in the SOAP header, and on the server side you'll need another
CallbackHandler which can provide the password for the user
(pulled
from LDAP) which WSS4J will compare to what's provided in the
UsernameToken and thus authenicate the message before your
service
(however it's implemented) ever gets called. it's quite
transparent
for the most part. it also inserts a few entries in the
MessageContext so you can later determine what kind of
authenication
has been done.
hth.
.......................ron.
Michael Rudolf wrote:
Is there any difference in case the Web Services are made
out of
Session EJBs? Or does WSS4J work the same way in that case?
Thanks!
Michael
you may want to look at WSS4J and UsernameTokens.
they're pretty
straight-forward as long as your client can support
them. they
are part of
the WS-Security standard if you want to stick with
"endorsed"
authentication
mechanisms. then on the server-side you'll typically
need a JNDI
interface to
your LDAP server to authenticate the user on that side.
hth.
................ron.
Hi,
is there any tutorial or example for authenticating
users of we
services
by username and pass over HTTPS? Can anybody explain in
more
detail how
this works? Is there any alternative to it? I want to
query axis
web
sercvices from a portal. That uses LDAP for
authetication. I
would like
to use the same directory for authenticating the users
at the web
services that are being queried.
Thanks for any help!
Michael