Announcement Announcement Module
Collapse
No announcement yet.
Oauth - invalid signature - plaintext for now Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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)
    Last edited by mihael.j; Oct 30th, 2012, 05:47 AM.

  • #2
    I can believe that there is a bug in the plaintext support. Please feel free to raise a ticket in JIRA, fix the bug and send a pull request if you have time (read the instructions in the README first).

    Comment

    Working...
    X