Oauth - invalid signature - plaintext for now
Hi, I am using scribe oauth client and spring oauth lib. I am quite new to this with but I managed to setup Tonr and Sparklr demo apps and they are working fine.
I am using scribe 1.3.2, spring 3.1.2, spring security 3.1.3, spring security oauth 1.0.0.-RC3
I've implemented a "GetRequestTokenServlet" servlet to implement the step where request token is obtained by consumer.
The servlet looks something like this...
UnauthenticatedRequestTokenProcessingFilter filter=new UnauthenticatedRequestTokenProcessingFilter();
// setup filter with all the required stuff
MyDefaults.initializeFilter(filter);
// this my stuff for logging only
CoreOAuthProviderSupport providerSupport2=new CoreOAuthProviderSupport();
Map<String, String > parametersParsed=providerSupport2.parseParameters( request);
System.out.println("received the following parameters: "+parametersParsed);
filter.setFilterProcessesUrl("/initiate");
filter.doFilter(request, response, new FilterChain() {
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1) throws IOException, ServletException {
System.out.println("Nothing further to do in this chain!");
}
});
System.out.println("TemporaryCredetialServlet - finished!");
My sample scribe oauth client looks as follows:
OAuthService service = new ServiceBuilder().provider(MyApi.class).callback(My ConsumerService.CONSUMER_CALLBACK_URL)
.apiKey(MyConsumerService.DEFAULT_CONSUMER_KEY).sc ope(MyScopeService.DEFAULT_SCOPE).signatureType(Si gnatureType.Header)
.debugStream(System.out)
.apiSecret(MyConsumerService.DEFAULT_CONSUMER_SECR ET).build();
System.out.println("=== My OAuth Prototype Workflow ===");
System.out.println();
// Obtain the Request Token
System.out.println("Fetching the Request Token...");
Token requestToken = service.getRequestToken();
System.out.println("Got the response for Request Token: "+requestToken.getRawResponse());
System.out.println("RequestToken: "+requestToken.getToken());
Everything works almost perfect. The problem is that in OAuthProviderProcessingFilter.validateSignature I get invalid signature error (I silenced this exception in spring oauth api so that I can get the complete flow trace).
First I switch to the PLAINTEXT method to check if signature base is the same on client and on server. Even in this case the signature verification fails. In debugger, I noticed that the signature is valid but what happens is that encoded and un-ecoded version of signature gets compared and evaluated as not-equal.
Client trace:
Fetching the Request Token...
obtaining request token from http://localhost:8085/test/initiate
setting oauth_callback to http://localhost:8085/test/callback
generating signature...
base string is: POST&http%3A%2F%2Flocalhost%3A8085%2Ftest%2Finitia te&oauth_callback%3Dhttp%253A%252F%252Flocalhost%2 53A8085%252Ftest%252Fcallback%26oauth_consumer_key %3DASampleConsumerKey%26oauth_nonce%3D3006752565%2 6oauth_signature_method%3DPLAINTEXT%26oauth_timest amp%3D1351588045%26oauth_version%3D1.0%26scope%3Dh ttp%253A%252F%252Flocalhost%253A8085%252Ftest%252F oauthprotectedsvc
Signature is: ASampleConsumerSecret&
appended additional OAuth parameters: { oauth_callback -> http://localhost:8085/test/callback , oauth_signature -> ASampleConsumerSecret& , scope -> http://localhost:8085/test/oauthprotectedsvc , oauth_version -> 1.0 , oauth_nonce -> 3006752565 , oauth_signature_method -> PLAINTEXT , oauth_consumer_key -> ASampleConsumerKey , oauth_timestamp -> 1351588045 }
using Http Header signature
sending request...
response status code: 200
response body: oauth_token=7457a361-1756-45a7-b081-75ccb69cbe5f&oauth_token_secret=aAslALNldWRK0qoU&o auth_callback_confirmed=true
Got the response for Request Token: oauth_token=7457a361-1756-45a7-b081-75ccb69cbe5f&oauth_token_secret=aAslALNldWRK0qoU&o auth_callback_confirmed=true
RequestToken: 7457a361-1756-45a7-b081-75ccb69cbe5f
Server debug/trace:
signature: ASampleConsumerSecret&
signatureBaseString: POST&http%3A%2F%2Flocalhost%3A8085%2Ftest%2Finitia te&oauth_callback%3Dhttp%253A%252F%252Flocalhost%2 53A8085%252Ftest%252Fcallback%26oauth_consumer_key %3DASampleConsumerKey%26oauth_nonce%3D3006752565%2 6oauth_signature_method%3DPLAINTEXT%26oauth_timest amp%3D1351588045%26oauth_version%3D1.0%26scope%3Dh ttp%253A%252F%252Flocalhost%253A8085%252Ftest%252F oauthprotectedsvc
The CoreOAuthSignatureMethodFactory says:
return new PlainTextSignatureMethod(oauthEncode(new StringBuilder(consumerSecret).append('&').append(t okenSecret).toString()), this.plainTextPasswordEncoder, salt);
In my case, token secret is empty, salt is null. This constructor will initialize PlainTextSigatureMethod as follows:
secret=ASampleConsumerSecret%26
encoder=PlaintTextPasswordEncoder
salt=null
and then later on verify is called
method.verify(signatureBaseString, signature); .. .where signature = ASampleConsumerSecret&
and this fails in the isPasswordValid ...
public void verify(String signatureBaseString, String signature) throws InvalidSignatureException {
if (this.encoder != null) {
if (!this.encoder.isPasswordValid(this.secret, signature, this.salt)) {
throw new InvalidSignatureException("Invalid signature for signature method " + getName());
}
}
else if (!signature.equals(this.secret)) {
throw new InvalidSignatureException("Invalid signature for signature method " + getName());
}
}
where this.secret=ASampleConsumerSecret%26
In debug, since I dont have source of PlainTextPasswordEncoder I can only see that there are two fields
pass1=ASampleConsumerSecret%26
pass2=ASampleConsumerSecret&
and they obviously don't match.
The PlaingTextPasswordEncoder says:
isPasswordValid(String encPass, String rawPass, Object salt)
Validates a specified "raw" password against an encoded password. This is ok from argument perspective as oauth API is passing encoded password in first argument and a raw password in second argument.
So what is the problem here? Thanks!
(Edit: switching to HMAC-SHA1 works and signature is validated ok, so it seems that plaintext validation method is not working properly)