简体   繁体   English

Spring OAuth 1.0支持:如何验证OAuth请求?

[英]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: 我必须支持旧式API,该API在单腿情况下将OAuth 1.0 POST请求发送到服务器:

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. 我收到一堆OAuth参数的请求,我想首先使用服务器上存储的机密进行验证。

Here is what I have done so far (which produces an exception): 这是我到目前为止所做的(产生异常):

Parameters the API sends: API发送的参数:

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 org.springframework.security.oauth.common.signature.InvalidSignatureException:签名方法HMAC-SHA1的无效签名

Secret is the same as is fed to remote api (double-checked!). 机密与提供给远程api的机密相同(请仔细检查!)。

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. 我觉得我在代码中有错误或API使用情况错了……很抱歉,但我在网上找不到任何示例。 Thanks you for any comment. 感谢您的任何评论。

OK, finally I found Spring's implementation of the OAuth 1.0 algorithm. 好的,最后我找到了Spring的OAuth 1.0算法的实现。 Basically the job is done in OAuthProviderProcessingFilter 基本上,这项工作是在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: Spring Boot v2.X的配置与​​此非常相似:

Configuring 0-legged OAuth 1.0 in Spring Boot 在Spring Boot中配置0足OAuth 1.0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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