axis-java-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ruchith Fernando <ruchith.ferna...@gmail.com>
Subject Re: Rampart STS Username service not returning password in callback
Date Wed, 30 Jan 2013 06:33:51 GMT
This issue is fixed in rampart trunk now.
With this fix the callback instance contains the incoming password for
the user to validate as required. Callback usage is set to
WSPasswordCallback.USERNAME_TOKEN.

Thanks,
Ruchith

On Thu, Jan 24, 2013 at 10:20 PM, Ruchith Fernando
<ruchith.fernando@gmail.com> wrote:
> Hi Guys,
>
> This seems to be a bug in WSS4J.
>
> In the plain text password case the validator[1] should simply load
> the password into the callback and let the callback handler take care
> of authentication.
> IIRC this was the behavior earlier with the use of
> WSPasswordCallback.USERNAME_TOKEN_UNKNOWN. This allows the service
> developer to store any derived/hashed form of the password and then
> use the callback handler to process incoming passwords.
>
> Thanks,
> Ruchith
>
> 1.) http://svn.apache.org/repos/asf/webservices/wss4j/tags/1_6_4/src/main/java/org/apache/ws/security/validate/UsernameTokenValidator.java
>
>
> On Mon, Jan 21, 2013 at 6:59 AM, Martin Gainty <mgainty@hotmail.com> wrote:
>>
>>
>>
>> ________________________________
>> From: brianreinhold@lampreynetworks.com
>> To: java-dev@axis.apache.org
>> Subject: RE: Rampart STS Username service not returning password in callback
>> Date: Sun, 20 Jan 2013 08:10:04 -0500
>>
>> Martin,
>>
>>
>>
>> I’m not sure I follow what you are saying. Are you suggesting there is a
>> means to accomplish the same thing (get actual sent password in the
>> callback) without changing the code AND is compliant with WS-Trust clients?
>>
>> MG>yes...take this example from
>> org.apache.ws.security.dom.handler.CallbackRefTest
>> MG>
>>
>> private CallbackHandler callbackHandler = new
>> UsernamePasswordCallbackHandler();
>>
>>   /**
>>      * A test for WSHandler.getPassword(...) where the password is obtained
>> from a
>>      * Callback Handler, which is obtained from the handler options using a
>> ref.
>>      */
>>     @org.junit.Test
>>     public void
>>     testHandlerOptionRef() throws Exception {
>>         final WSSConfig cfg = WSSConfig.getNewInstance();
>>         final RequestData reqData = new RequestData();
>>         reqData.setWssConfig(cfg);
>>         reqData.setUsername("alice");
>>         reqData.setPwType(WSConstants.PW_DIGEST);    // type of requested
>> Password from response can be PW_TEXT
>>         reqData.setMsgContext(new java.util.TreeMap<String, String>());
>>         final java.util.List<Integer> actions = new
>> java.util.ArrayList<Integer>();
>>
>> /* Here are the options for our actions
>>
>>  public static final int NO_SECURITY = 0;
>>     public static final int UT = 0x1; // perform UsernameToken
>>     public static final int SIGN = 0x2; // Perform Signature
>>     public static final int ENCR = 0x4; // Perform Encryption
>>
>>     public static final int ST_UNSIGNED = 0x8; // perform SAMLToken unsigned
>>     public static final int ST_SIGNED = 0x10; // perform SAMLToken signed
>>
>>     public static final int TS = 0x20; // insert Timestamp
>>     public static final int UT_SIGN = 0x40; // perform signature with UT
>> secret key
>>     public static final int SC = 0x80;      // this is a
>> SignatureConfirmation
>>
>> */
>>
>>       int action=Integer.valueOf(WSConstants.UT);
>>         actions.add(action);
>>
>> /*
>>
>> where UsernameToken class contains both username AND password elements
>>
>>    private Element elementUsername = null;
>>     private Element elementPassword = null;
>>
>> */
>>
>> /* what is the soap envelope we will use for our document    public static
>> final String SAMPLE_SOAP_MSG =
>>         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
>>         + "<SOAP-ENV:Envelope "
>>         +   "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" "
>>         +   "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
>>         +   "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
>>         +   "<SOAP-ENV:Body>"
>>         +       "<add
>> xmlns=\"http://ws.apache.org/counter/counter_port_type\">"
>>         +           "<value xmlns=\"\">15</value>"
>>         +       "</add>"
>>         +   "</SOAP-ENV:Body>"
>>         + "</SOAP-ENV:Envelope>";
>>
>> */
>>
>> //construct a simple SoapEnvelope doc with counter_port_type set to 15
>>         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
>>         CustomHandler handler = new CustomHandler();
>>
>> //public static final String PW_CALLBACK_CLASS = "passwordCallbackClass";
>>         handler.setOption(WSHandlerConstants.PW_CALLBACK_REF,
>> callbackHandler);
>>
>> //Notice the handler has not set the password but expects password from
>> response created by callback
>>         handler.send(
>>             WSConstants.UT,
>>             doc,
>>             reqData,
>>             actions,
>>             true
>>         );
>>
>>         String outputString =
>>             XMLUtils.PrettyDocumentToString(doc);
>>         if (LOG.isDebugEnabled()) {
>>             LOG.debug(outputString);
>>         }
>>         assertTrue(outputString.indexOf("alice") != -1);
>>         assertTrue(outputString.indexOf("securityPassword") != -1);
>>     }
>> MG>
>>
>>
>>
>> In any case, I think it’s an oversight by WSS4J that they require that the
>> service must KNOW the password. In the code I see no way to avoid the issue.
>> In all cases when the user’s (my) callback routine is signaled, the callback
>> passed to the user always has the password set to null and the user’s
>> callback routine is expected to provide the actual password. The latter part
>> is okay as a means to validate the password is okay, but what WSS4J needs to
>> do then is to provide a second routine, getSentPassword() which is the value
>> of the sent password, clear or digested.
>>
>> MG> recalling the password type is set in the RequestData
>> MG> reqData.setPwType(WSConstants.PW_TEXT);
>>
>> MG> String getSentPassword(Document doc,RequestedData
>> reqData,CallbackHandler callbackHandler,int Action,WSHandler handler)
>>
>>  {
>>   if(reqData.getPwType().equals(WSConstants.PASSWORD_DIGEST)
>>
>>   {
>>
>>    List<WSSecurityEngineResult> results =
>> secEngine.processSecurityHeader(doc, null, callbackHandler, null);
>>
>>    WSSecurityEngineResult actionResult =
>> WSSecurityUtil.fetchActionResult(results, WSConstants.UT);
>>     UsernameToken receivedToken =
>>         (UsernameToken)
>> actionResult.get(WSSecurityEngineResult.TAG_USERNAME_TOKEN);
>>       return receivedToken.hashCode());
>>
>>   }
>>
>>   if(reqData.getPwType().equals(WSConstants.PASSWORD_TEXT)
>>
>>   {
>>
>>     callbackHandler=getPasswordCallbackHandler(reqData);
>>
>>     WSPasswordCallback password_callback=handler.getPasswordCB(
>>          reqData.getUsername(),
>>          action,
>>          callbackHandler,
>>          reqData);
>>      return password_callback.getPassword();
>>
>>    }
>>
>> }
>> MG>
>>
>>
>>
>> This would allow the service to respond as it sees fit. In my case that
>> would be storing a password digest so my service (and a successful hacker)
>> would never be able to know the real passwords.
>>
>>
>>
>> I would do that except the callback created implements ‘Callback’ which is
>> not part of WSS4J. Changing that interface looks like it would have FAR
>> reaching consequences.
>> MG>i think we can use WSPasswordCallback password_callback =
>> handler.getPasswordCB from WSHandler
>>
>>
>>
>> Brian
>> MG>WDYT
>>
>>
>>
>> From: Martin Gainty [mailto:mgainty@hotmail.com]
>> Sent: Saturday, January 19, 2013 7:40 PM
>> To: java-dev@axis.apache.org
>> Subject: RE: Rampart STS Username service not returning password in callback
>>
>>
>>
>>
>>
>>
>>
>> ________________________________
>>
>> From: brianreinhold@lampreynetworks.com
>> To: java-dev@axis.apache.org
>> Subject: RE: Rampart STS Username service not returning password in callback
>> Date: Sat, 19 Jan 2013 08:58:15 -0500
>>
>> Hi Martin,
>>
>>
>>
>> I did something different. The problem is in WSS4J. In the
>> UsernameTokenValidation file I simply passed the password to the callback
>> constructor which was previously null. Now I have to change the approach a
>> little bit. In my handler I read the password, do my hash, and if it matches
>> my stored hash I do nothing since the password is already set. This will
>> cause WSS4J to accept the message. If it doesn’t match I set the password to
>> current password + “bad” just to make it different causing the message to be
>> rejected.
>>
>>
>>
>> I don’t like it but I really saw no other choice and don’t understand why
>> WSS4J didn’t give the choice. They could have added another variable
>> ‘rawPassword’ and a getter for it. This would allow the service to use the
>> raw password for whatever purpose it needs. The user would still set
>> ‘password’ as expected by WSS4J.
>>
>> MG>take a look at the org.apache.ws.security.dom.message.WSSecUsernameToken
>> getSecretKey
>>
>> MG>/**
>>      * getSecretKey
>>      *
>>      * After the <code>prepare()</code> method was called use this method
>>      * to compute a derived secret key. If "useDerivedKey" is set, then the
>> returned secret
>>      * key is derived as per the UsernameToken 1.1 specification. Otherwise,
>> the generation
>>      * of this secret key is according to the WS-Trust specifications.
>>      *
>>      * @return Return the derived secret key of this token or null if
>> <code>prepare()</code>
>>      * was not called before.
>>      */
>>
>> MG>boolean useDerivedKey is set to false initially so the secretKey coming
>> back from WSS4J is a WS-Trust compliant secretKey
>> MG>setting plain text Password can be accomplished with
>> MG>setPasswordType(WSConstants#PASSWORD_TEXT)
>> MG>setPasswordsAreEncoded(false)
>> MG>the prepare method sets the password into the UsernameToken object (in
>> the prepare method)
>>
>> MG>ut.setPassword(password);
>>
>>
>>
>> It works and I can store passwords as hashes and be interoperable with the
>> WS-Trust standard.
>>
>> MG>you have a solution..and thats all that matters
>> MG>congrats on acquiring a WS-Trust solution!..i hope the journey was
>> pleasant and as informative for you as  it was for me
>>
>>
>>
>> Brian
>>
>> MG>Martin
>>
>>
>>
>> From: Martin Gainty [mailto:mgainty@hotmail.com]
>> Sent: Friday, January 18, 2013 11:24 PM
>> To: java-dev@axis.apache.org
>> Subject: RE: Rampart STS Username service not returning password in callback
>>
>>
>>
>> Hi Brian
>>
>> assume your CallbackHandler looks something like like
>>
>> public class PWCBHandler implements
>> javax.security.auth.callback.CallbackHandler {
>>     public void handle(javax.security.auth.callback.Callback[] callbacks)
>> throws IOException,
>>             javax.security.auth.callback.UnsupportedCallbackException {
>>         for (int i = 0; i < callbacks.length; i++) {
>>              org.apache.ws.security.WSPasswordCallback pwcb =
>> (org.apache.ws.security.WSPasswordCallback)callbacks[i];
>>
>> put the CallbackHandler into the Options class for the serviceClient to
>> pickup e.g.
>>
>> Options options = client.getOptions();
>> options.put(WSHandlerConstants.PW_CALLBACK_REF, new
>> PasswordCallbackHandler());
>>
>>  serviceClient.setOptions(options);
>>                 try {
>>                     //Blocking invocation
>>                     serviceClient.sendReceive(getOMElement());
>>                     fail("Service Should throw an error..");
>>                 } catch (AxisFault axisFault) {
>>                     assertEquals("Testing negative scenarios with Apache
>> Rampart. Intentional Exception", axisFault.getMessage());
>>                 }
>>
>> http://wso2.org/library/3733
>>
>> HTH,
>> Martin
>> ______________________________________________
>> Verzicht und Vertraulichkeitanmerkung/Note de déni et de confidentialité
>>
>> Diese Nachricht ist vertraulich. Sollten Sie nicht der vorgesehene
>> Empfaenger sein, so bitten wir hoeflich um eine Mitteilung. Jede unbefugte
>> Weiterleitung oder Fertigung einer Kopie ist unzulaessig. Diese Nachricht
>> dient lediglich dem Austausch von Informationen und entfaltet keine
>> rechtliche Bindungswirkung. Aufgrund der leichten Manipulierbarkeit von
>> E-Mails koennen wir keine Haftung fuer den Inhalt uebernehmen.
>>
>> Ce message est confidentiel et peut être privilégié. Si vous n'êtes pas le
>> destinataire prévu, nous te demandons avec bonté que pour satisfaire
>> informez l'expéditeur. N'importe quelle diffusion non autorisée ou la copie
>> de ceci est interdite. Ce message sert à l'information seulement et n'aura
>> pas n'importe quel effet légalement obligatoire. Étant donné que les email
>> peuvent facilement être sujets à la manipulation, nous ne pouvons accepter
>> aucune responsabilité pour le contenu fourni.
>>
>>
>>
>>
>>
>> ________________________________
>>
>> From: brianreinhold@lampreynetworks.com
>> To: java-dev@axis.apache.org
>> Subject: RE: Rampart STS Username service not returning password in callback
>> Date: Fri, 18 Jan 2013 12:01:19 -0500
>>
>> Martin,
>>
>>
>>
>> Can you tell me where the password callback in my service gets called from?
>> It’s the password callback configured by the following line in the STS
>> service.xml
>>
>>
>>
>>
>> <ramp:passwordCallbackClass>com.lni.exchange.wan.receive.binding.axis2.PasswordCallback</ramp:passwordCallbackClass>
>>
>>
>>
>>
>>
>> Brian
>>
>>
>>
>> From: Martin Gainty [mailto:mgainty@hotmail.com]
>> Sent: Wednesday, January 16, 2013 5:14 PM
>> To: java-dev@axis.apache.org
>> Subject: RE: Rampart STS Username service not returning password in callback
>>
>>
>>
>> http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd
>>
>> i think I found an element we can use
>>
>> (where both noonce and Password would be child elements of
>> wsc:DerivedKeyToken) so here is the TestCase
>>
>>  org.apache.rampart.handler.config.OutflowConfiguration ofc = new
>> org.apache.rampart.handler.config.OutflowConfiguration();
>>
>>   ofc.setActionItems("UsernameToken Encrypt");
>>   ofc.setUser("Mohammed");
>>   ofc.setAddUTElements("Nonce Created");  //Noonce
>>   ofc.setEncryptionParts("{Element}{" + WSSE_NS + "}UsernameToken");
>>   ofc.setEncryptionUser("osama");
>>   ofc.setEncryptionPropFile("interop.properties");
>>   ofc.setPasswordCallbackClass("org.apache.axis2.security.PWCallback");
>>   ofc.setEncryptionSymAlgorithm(WSConstants.TRIPLE_DES);  //change this to
>> MD5 or SHA-1
>>   ofc.setPasswordType(WSConstants.PW_TEXT);
>>   ofc.setEncryptionKeyIdentifier(WSSHandlerConstants.SKI_KEY_IDENTIFIER);
>>
>> //so here is the new OutFlowConfiguration Element
>>    ofc.setPassword("YadaYadaYada");
>>
>>   return ofc;
>>
>> //org.apache.rampart.handler.config.OutflowConfiguration change
>>  public void setPassword(String passwordType) {
>>   this.actionList[this.currentAction].put(
>>     WSHandlerConstants.PASSWORD, password);
>>  }
>> //org.apache.ws.security.dom.handler.WSHandlerConstants add this element
>> public static final String PASSWORD = "password"
>>
>> //correct ...why touch WSS4J for one minor update to a constant ..(maybe
>> using constant "password" is better)
>>
>> //org.apache.rampart.handler.config.OutflowConfiguration change with
>> constant
>> public void setPassword(String passwordType) {
>> this.actionList[this.currentAction].put(
>>     "password", password);
>> }
>>
>> reference
>> http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd
>>
>> WDYT?
>> Martin
>>></xsd:
>>
>> ________________________________
>>
>> No virus found in this message.
>> Checked by AVG - www.avg.com
>> Version: 2013.0.2890 / Virus Database: 2638/6037 - Release Date: 01/16/13
>>
>> No virus found in this message.
>> Checked by AVG - www.avg.com
>> Version: 2013.0.2890 / Virus Database: 2638/6037 - Release Date: 01/16/13
>>
>> ________________________________
>>
>> No virus found in this message.
>> Checked by AVG - www.avg.com
>> Version: 2013.0.2890 / Virus Database: 2639/6041 - Release Date: 01/18/13
>>
>> No virus found in this message.
>> Checked by AVG - www.avg.com
>> Version: 2013.0.2890 / Virus Database: 2639/6041 - Release Date: 01/18/13
>>
>> ________________________________
>>
>> No virus found in this message.
>> Checked by AVG - www.avg.com
>> Version: 2013.0.2890 / Virus Database: 2639/6045 - Release Date: 01/20/13
>>
>> No virus found in this message.
>> Checked by AVG - www.avg.com
>> Version: 2013.0.2890 / Virus Database: 2639/6045 - Release Date: 01/20/13
>
>
>
> --
> http://ruchith.org



-- 
http://ruchith.org

---------------------------------------------------------------------
To unsubscribe, e-mail: java-dev-unsubscribe@axis.apache.org
For additional commands, e-mail: java-dev-help@axis.apache.org


Mime
View raw message