简体   繁体   中英

Spring OAuth 1.0 support: how to verify OAuth request?

I have to support a legacy API that sends OAuth 1.0 POST request to my server in one-legged scenario:

I get a request with the bunch of OAuth-parameters which I want to verify (in the first place) with a secret stored on server.

Here is what I have done so far (which produces an exception):

Parameters the API sends:

key :: launch_presentation_return_url
value :: 
key :: lti_version
value :: LTI-1p0
key :: user_id
value :: student
key :: roles
value :: Instructor
key :: oauth_nonce
value :: 160455874400102142031543488380
key :: oauth_timestamp
value :: 1543488380
key :: lis_result_sourcedid
value :: course-v1%3Aedx-integration-initiative%2B123456%2B2018_T2:-de03e087e09d4629ab61ee44cea69b43:student
key :: context_id
value :: course-v1:edx-integration-initiative+123456+2018_T2
key :: oauth_consumer_key
value :: the_client_key
key :: resource_link_id
value :: -de03e087e09d4629ab61ee44cea69b43
key :: oauth_signature_method
value :: HMAC-SHA1
key :: oauth_version
value :: 1.0
key :: lis_outcome_service_url
value :: /preview/xblock/block-v1:edx-integration-initiative+123456+2018_T2+type@lti+block@de03e087e09d4629ab61ee44cea69b43/handler/grade_handler
key :: oauth_signature
value :: 9ENcuZRA6akEc+cM753GB+zPzLE=
key :: lti_message_type
value :: basic-lti-launch-request
key :: oauth_callback
value :: about:blank

My controller:

@PostMapping("/api/start")
    @ResponseBody
    public String start(HttpServletRequest request) throws Exception {

        String key = request.getParameter("oauth_consumer_key");
        String signature = request.getParameter("oauth_signature");

        // ...code to retrieve secret from DB based on key
        String secret = "my_client_secret";

            // Spring processing
            CoreOAuthProviderSupport providerSupport = new CoreOAuthProviderSupport();
String signatureBaseString = providerSupport.getSignatureBaseString(request);

        SecretKey secretKey = new SecretKeySpec(secret.getBytes(), "AES"); 
        HMAC_SHA1SignatureMethod signatureMethod = new HMAC_SHA1SignatureMethod(secretKey);
        signatureMethod.verify(signatureBaseString, signature);
        System.out.println("Success verification");
        return "Success";
    }

This controller fails with:

org.springframework.security.oauth.common.signature.InvalidSignatureException: Invalid signature for signature method HMAC-SHA1

Secret is the same as is fed to remote api (double-checked!).

How can I make it work? I feel like I have a mistake in the code or wrong API usage case... Sorry but I failed to find any example in the net. Thanks you for any comment.

OK, finally I found Spring's implementation of the OAuth 1.0 algorithm. Basically the job is done in OAuthProviderProcessingFilter

The code fragment that does it looks like this:

  /**
   * Validate the signature of the request given the authentication request.
   *
   * @param authentication The authentication request.
   */
  protected void validateSignature(ConsumerAuthentication authentication) throws AuthenticationException {
    SignatureSecret secret = authentication.getConsumerDetails().getSignatureSecret();
    String token = authentication.getConsumerCredentials().getToken();
    OAuthProviderToken authToken = null;
    if (token != null && !"".equals(token)) {
      authToken = getTokenServices().getToken(token);
    }

    String signatureMethod = authentication.getConsumerCredentials().getSignatureMethod();
    OAuthSignatureMethod method;
    try {
      method = getSignatureMethodFactory().getSignatureMethod(signatureMethod, secret, authToken != null ? authToken.getSecret() : null);
    }
    catch (UnsupportedSignatureMethodException e) {
      throw new OAuthException(e.getMessage(), e);
    }

    String signatureBaseString = authentication.getConsumerCredentials().getSignatureBaseString();
    String signature = authentication.getConsumerCredentials().getSignature();
    if (log.isDebugEnabled()) {
      log.debug("Verifying signature " + signature + " for signature base string " + signatureBaseString + " with method " + method.getName() + ".");
    }
    method.verify(signatureBaseString, signature);
  }

The Spring Boot v2.X configuration looks pretty similar to this one:

Configuring 0-legged OAuth 1.0 in Spring Boot

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM