Results 1 to 5 of 5

Thread: OAuth 1.0 and extra request parameters

  1. #1
    Join Date
    Sep 2008
    Location
    Kiev, Ukraine
    Posts
    14

    Exclamation OAuth 1.0 and extra request parameters

    Hi All,
    Got problems while signing post request with extra parameters. As I read, request parameters, using method POST should be specified in request body and request should have header - "Content-Type: application/x-www-form-urlencoded".
    I use next code for that:
    Code:
    MultiValueMap postParams = new LinkedMultiValueMap();
    postParams.add("status", "Update my status on Twitter");
    authRestTemplate.postForLocation("http://api.twitter.com/1/statuses/update.xml", postParams);
    To write postParams to request body template uses standard FormHttpMessageConverter. But, problem is, that messageConverter writes parameters to body AFTER OAuthClientHttpRequestFactory signed request, thus parameter status="Update my status on Twitter" is not used on making signature:
    Code:
    String queryString = this.support.getOAuthQueryString(this.resource, accessToken, uri.toURL(), httpMethod.name(), this.additionalOAuthParameters);
    So, this problem exists only for POST methods, because for GET methods in CoreOAuthConsumerSupport.loadOAuthParameters(...)
    Code:
    String query = requestURL.getQuery();
        if (query != null) {
    //here, all params from query are handled correctly
    }
    all parameter in query are parsed and used to calculate signatures.
    Any ideas, how to fix it?
    Code:
    if (var) return true;
    else if (!var) return false;
    else return !true&&!false; // :-)

  2. #2
    Join Date
    May 2008
    Location
    Salt Lake City
    Posts
    167

    Default

    That would probably be a bug. Can you open a JIRA issue describing the problem and expected behavior?

  3. #3
    Join Date
    Sep 2008
    Location
    Kiev, Ukraine
    Posts
    14

    Default

    Not sure. I think RestTemplate + oauth HttpFactory decoration is not suitable for it at all. I thought about it and ended up by writing own MessageConverter for that.
    Does anybody from this project tell me his thoughts about it?
    Here is my code (mainly copy-pasted from OAuthClientHttpRequestFactory):
    Code:
    public class OAuthPostMessageConverter extends FormHttpMessageConverter {
    
        private ProtectedResourceDetails resource;
        private OAuthConsumerSupport support =  new CoreOAuthConsumerSupport();;
        
        @Override
        public void write(MultiValueMap<String, ? > map, MediaType contentType,
            HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
            OAuthSecurityContext context = OAuthSecurityContextHolder.getContext();
            ClientHttpRequest req = (ClientHttpRequest) outputMessage;
            if (context == null) {
              throw new IllegalStateException("No OAuth security context has been established. Unable to access resource '" + this.resource.getId() + "'.");
            }
    
            Map<String, OAuthConsumerToken> accessTokens = context.getAccessTokens();
            OAuthConsumerToken accessToken = accessTokens == null ? null : accessTokens.get(this.resource.getId());
            if (accessToken == null) {
              throw new AccessTokenRequiredException("No OAuth security context has been established. Unable to access resource '" + this.resource.getId() + "'.", resource);
            }
            Map<String, String> params = new HashMap<String, String>();
            for (Map.Entry<String, ?> entry : map.entrySet()) {
                @SuppressWarnings("unchecked")
                List<String> value= (List<String>) entry.getValue();
                params.put(entry.getKey(), value.get(0));
            }
            String authHeader = this.support.getAuthorizationHeader(this.resource, accessToken, req.getURI().toURL(), req.getMethod().name(), params);
            req.getHeaders().add("Authorization", authHeader);
    
            super.write(map, contentType, outputMessage);
        }
    
        
        public void setResource(ProtectedResourceDetails resource) {
            this.resource = resource;
        }
    
        
        public void setSupport(OAuthConsumerSupport support) {
            this.support = support;
        }
    
    }
    Last edited by Hunger; Feb 22nd, 2011 at 08:46 AM.
    Code:
    if (var) return true;
    else if (!var) return false;
    else return !true&&!false; // :-)

  4. #4
    Join Date
    May 2008
    Location
    Salt Lake City
    Posts
    167

    Default

    I think you've got the right idea. I think the RestTemplate is used primarily for convenience, but it looks like in your case you have to do this with custom code. But it sounds like something like this could be provided as an additional utility.

  5. #5
    Join Date
    Sep 2008
    Location
    Kiev, Ukraine
    Posts
    14

    Default

    Again, not sure. I think oauth rest template's logic is wrong. It signs request BEFORE code manipulation, but it should do it AFTER all manipulations with request, because content of request could be changed in any place, thus auth signature become wrong.
    Code:
    if (var) return true;
    else if (!var) return false;
    else return !true&&!false; // :-)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •