you might want to read this doc first - http://ws.apache.org/wss4j/axis.html
it covers much of what you're talking about.  unfortunately it's a bit out of
date, but it's a start.  you'll then want to read this doc -
http://ws.apache.org/wss4j/package.html - it's also a little dated, but covers
more involved topics and in more detail.  (these docs should probably be moved
into the wiki...)

anyway, in the second doc it specifies that to control the password type you
use this parameter in your client-config.wsdd:
    <parameter name="passwordType" value="PasswordText" />
(versus "PasswordDigest")

hth.
................ron.
p.s., by "in my src" i meant in my copy of the WSS4J source (which is a few
months old) - http://www.apache.org/dyn/closer.cgi/ws/wss4j/


> Ok...im getting a bit confused here...
>
>>i had wondered that one myself.  you can configure WSS4J to send the password
>>in your UsernameToken as plaintext instead of SHA-1 digest.  so i guess your
>>client can send the encrypted password as plaintext and then your server
>> would
>>compare that encrypted value with what's stored in LDAP.
>>
> How do i do that? The callback class sets the pw. I cant even access it
> in there. How does the pw sent from the client get to the server into
> the callback class?
>
>>  doesn't seem
>>terribly secure in that case, tho, but otherwise the client would need access
>>to the plaintext password, as would the server because the callback handler
>>never gets the password that was sent by the client - all that work happens
>> in
>>
>>org.apache.ws.security.WSSecurityEngine.handleUsernameToken(Element token,
>>CallbackHandler cb).
>>
>>NOTE, i remember seeing a post about a bug in the password comparison code
>> and
>>i think it's in this method.  it appears from the code that the passwords are
>>only compared if it's a digest password (with nonce != null && createdTime !=
>>null).  otherwise the lines (856-858 in my src)
>>
>>
> did you send your src? i didnt see it...sorry...
>
>>if (!passDigest.equals(password)) {
>>  throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
>>}
>>
>>are skipped entirely!  um, WSS4J folks - this has been fixed, right?
>>
>>
>>
>>
>>
>>>And another question on this one...my passwords in the LDAP dir are
>>>encrypted as they are migrated from a UNIX passwd file. The Callback
>>>Class actually expects me to set the password. How did you do the actual
>>>authentication then? Can i read the pass in cleartext? I need a
>>>cleartext pass later in the process for an ssh connection. Any ideas on
>>>how to do this?
>>>
>>>
>>>
>>>>the handler for exracting the login name?  that's basically the code i
>>>>included below to extract from the incoming message, then create the user
>>>>object, hit the LDAP server (through JNDI api) and then store (actually in
>>>> a
>>>>thread-local so even non-Axis code can get the current user).  the rest is
>>>> to
>>>>include it thus in your server-config.wsdd:
>>>>
>>>> <service name="FreezerWS" provider="java:RPC" style="document"
>>>>use="literal">
>>>>   <!-- WS-Security handlers -->
>>>>   <requestFlow>
>>>>     <!-- the header that carries the user's login-name -->
>>>>     <handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
>>>>       <parameter name="action"                value="UsernameToken"/>
>>>>       <parameter name="actor"                 value="loginName"/>
>>>>       <parameter name="passwordCallbackClass"
>>>>value="ServerSidePWCallback"/>
>>>>     </handler>
>>>>
>>>>     <!-- add a handler that populates the session given the user's
>>>>login-name -->
>>>>     <handler
>>>>type="java:com.amgen.seattle.appdev.freezer.webservice.server.WSLoginNameHandler">
>>>>       <!-- the actor of the UsernameToken header with the login-name -->
>>>>       <parameter name="headerActor" value="loginName"/>
>>>>     </handler>
>>>>   </requestFlow>
>>>>
>>>>that's about it.
>>>>
>>>>the best documentation on WSS4J (or at least links to it) SHOULD be in the
>>>>Wiki ( http://wiki.apache.org/ws/FrontPage/WsFx ) but i'm not certain one
>>>>could say that yet...  i keep a short list of good resources i've found
>>>> here
>>>>http://wiki.apache.org/ws/RonReynolds/Wss4jLinks but it's only a handful of
>>>>links but it might give you a starting point. :)  search around in the Wiki
>>>>and then your next best bet are the 2 wss4j docs and then Google...
>>>>
>>>>..................ron.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>>Thx for your help. I figured it out now. Didnt see one section of the
>>>>>WSS4J documentation. You can set the EngineConfiguration to use a wsdd
>>>>>file inside the program code. As long as this is readable from the
>>>>>servlet everythings fine.
>>>>>Is there any good tutorial or documentation on developing these Handlers
>>>>>like you explained below? I dunno if you mind sharing your Handler
>>>>>implementation. It would be interesting to see how you did this.
>>>>>Thanks alot!
>>>>>Michael
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>i haven't tried this.  it certainly must be possible, but right now i
>>>>>>haven't
>>>>>>the time to figure it out.
>>>>>>
>>>>>>i would start at MessageContext.getAxisEngine().getGlobalRequest() and
>>>>>>search
>>>>>>in that area.  the file itself is loaded by
>>>>>>org.apache.axis.configuration.EngineConfigurationFactoryDefault.  also i
>>>>>>seem
>>>>>>to remember someone mentioning that you could access the global request
>>>>>>flow
>>>>>>and insert a handler into that flow at runtime.  also if you have
>>>>>>permissions
>>>>>>you can call System.setProperty() from a startup servlet (if you want a
>>>>>>possibly much simpler solution that opens up a bunch of possible bugs if
>>>>>>another servlet in the same servlet engine tries to connect to a
>>>>>> different
>>>>>>web
>>>>>>service...)
>>>>>>
>>>>>>sorry i couldn't be of more help. :-/
>>>>>>...............ron.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>>Ok...i dont use the client_deploy.wsdd....is there any way to avoid
>>>>>>>using it? I have the client inside a servlet so i cant specify it with
>>>>>>>the java -D.... command line.
>>>>>>>Thx!
>>>>>>>Michael
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>do you have this in your client-config.wsdd?
>>>>>>>><deployment ...>
>>>>>>>><transport .../>
>>>>>>>><globalConfiguration>
>>>>>>>> <requestFlow>
>>>>>>>>   <!-- add the header that carries the user's login-name -->
>>>>>>>>   <handler type="java:org.apache.ws.axis.security.WSDoAllSender">
>>>>>>>>     <parameter name="action" value="UsernameToken"/>
>>>>>>>>     <parameter name="actor"  value="loginName"/>
>>>>>>>>     <parameter name="passwordCallbackClass" value="PWCallback"/>
>>>>>>>>   </handler>
>>>>>>>>?
>>>>>>>>
>>>>>>>>otherwise there won't be any handler in the request flow that knows
>>>>>>>> what
>>>>>>>>to
>>>>>>>>do
>>>>>>>>with those properties.
>>>>>>>>
>>>>>>>>hth.
>>>>>>>>.............ron.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>>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
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>>
>>
>>
>>
>
>


Reply via email to