简体   繁体   English

Groovy - 使用 HttpBuilder 的 Jira OAuth 集成

[英]Groovy - Jira OAuth integration using HttpBuilder

I want to get data using JIRA REST api with provided JIRA OAuth authentication service.我想使用JIRA REST api和提供的JIRA OAuth authentication服务获取数据。

Basically I'm able to achieve this task using ScribeJava with Groovy .基本上我可以使用带有Groovy ScribeJava来完成这个任务。 But I want to decoupled all the process as below :-但我想将所有过程解耦如下:-

  • Request to get request token请求获取请求令牌
  • Request to get authorized URL请求获取授权 URL
  • Request to access token请求访问令牌
  • Request to get actual data using HTTPBuilder请求使用HTTPBuilder获取实际数据

So I'm able to achieve above mentioned first three steps using ScribeJava and storing the accessToken into Database for further request for data as below :-所以,我能够达到上述提到使用前三个步骤ScribeJava和存储accessTokenDatabase的数据,如下面进一步的要求: -

import java.security.KeyFactory
import java.security.PrivateKey
import java.security.spec.PKCS8EncodedKeySpec

import com.github.scribejava.core.builder.api.DefaultApi10a
import com.github.scribejava.core.model.OAuth1RequestToken
import com.github.scribejava.core.services.RSASha1SignatureService
import com.github.scribejava.core.services.SignatureService


class JiraOauthProvider extends DefaultApi10a {

    private String authURL
    private String requestTokenURL
    private String accessTokenURL
    private String consumerPrivateKey

    private JiraOauthProvider(authURL, requestTokenURL, accessTokenURL, consumerPrivateKey) {
        this.authURL = authURL
        this.requestTokenURL = requestTokenURL
        this.accessTokenURL = accessTokenURL
        this.consumerPrivateKey = consumerPrivateKey
    }

    private static JiraOauthProvider instance = null

    public static JiraOauthProvider instance(Map map) {
        if(instance == null) {
            instance = new JiraOauthProvider(map.authURL,
                    map.requestTokenURL,
                    map.accessTokenURL,
                    map.consumerPrivateKey)
        }
        return instance
    }

    @Override
    public String getAccessTokenEndpoint() {
        return accessTokenURL
    }

    @Override
    public String getRequestTokenEndpoint() {
        return requestTokenURL
    }

    @Override
    public String getAuthorizationUrl(OAuth1RequestToken requestToken) {
        return String.format(authURL, requestToken.getToken())
    }

    @Override
    public SignatureService getSignatureService() {
        return new RSASha1SignatureService(getPrivateKey())
    }

    private PrivateKey getPrivateKey() {
        byte[] key = Base64.getDecoder().decode(consumerPrivateKey)
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(key)
        KeyFactory kf = KeyFactory.getInstance("RSA")
        return kf.generatePrivate(keySpec)
    }

Now I'm building OAuthService as :-现在我将OAuthService构建为:-

private static final String CALLBACK_URI = "callback-url"
protected static final String CONSUMER_KEY = "consumer-key"
protected static final String CONSUMER_PRIVATE_KEY = "private-key"

Map oAuthMap = [
                "authURL" :"auth-url=%s",
                "requestTokenURL":"request-token-url",
                "accessTokenURL":"access-token-url",
                "consumerPrivateKey":CONSUMER_PRIVATE_KEY
            ]

//Buid oauth service to get request token, auth url and access token
OAuth10aService service = ServiceBuilder()
                .apiKey(CONSUMER_KEY)
                .apiSecret(CONSUMER_PRIVATE_KEY).callback(CALLBACK_URI)
                .build(JiraOauthProvider.instance(oAuthMap))

OAuth1RequestToken requestToken = service.getRequestToken()
def authURL = service.getAuthorizationUrl(requestToken)

//Now after redirect to this authURL and providing credential I'm getting oauthVerifier code to get accessToken and secretToken

def oauthVerifier = "oauth verifier code"

//Now calling to get accessToken
OAuth1AccessToken oAuth1AccessToken = service.getAccessToken(requestToken, oauthVerifier);
def accessToken = oAuth1AccessToken.getToken()
def secretToken = oAuth1AccessToken.getTokenSecret()
//now I'm storing this `accessToken`and `secretToken` into DB for further future data request.

So after all above stuff I'm able to achieve above mentioned three steps and storing the access token into db for future request only for data .所以毕竟上面的东西我能够实现上述三个步骤并将访问令牌存储到db以便将来仅请求data

So to achieve 4th step to getting actual data using HTTPBuilder I'm doing some thing as below :-因此,为了实现使用HTTPBuilder获取实际数据的第 4 步,我正在执行以下操作:-

def http  = new HTTPBuilder('base-url')

http.auth.oauth CONSUMER_KEY, CONSUMER_PRIVATE_KEY, accessToken, secretToken

http.request(Method.GET, ContentType.JSON) { req ->
            uri.path = 'path'
            response.success = { resp, json ->
                println json
            }
            response.failure = { resp, json -> print json }
        }
    }

But I'm getting response as :-但我得到的回应是:-

{oauth_problem=signature_method_rejected}

So, could anyone suggest me how can I get actual data using HTTPBuilder with OAuth authentication using accessToken and secretToken?所以,任何人都可以建议我怎么能得到使用实际数据HTTPBuilderOAuth使用认证accessToken和secretToken?

Note :- I can get actual data as well using ScribeJava Api with OAuthRequest but requirement is to get actual data using HTTPBuilder注意:- 我也可以使用带有OAuthRequest ScribeJava Api 获取实际数据,但要求是使用HTTPBuilder获取实际数据

I just want a pointer that how to achieve it.我只想要一个如何实现它的指针。

After lot of search I have got the solution from here .经过大量搜索,我从这里得到了解决方案。 Actually HTTPBuilder internally using Signpost which signing the request using HmacSha Signer while Jira rest api supports RSA-SHA1 Signer to validate the HttpRequest that's why it's giving response as :-实际上, HTTPBuilder内部使用Signpost ,它使用HmacSha Signer对请求进行HmacSha SignerJira rest api支持RSA-SHA1 Signer来验证HttpRequest ,这就是它给出响应的原因:-

{oauth_problem=signature_method_rejected}

So, basically I have to do custom RSA-SHA1 Signer to get the signature to http request.所以,基本上我必须做自定义RSA-SHA1 Signer来获取 http 请求的签名。 To achive this I'm using Google Data (GData) APIs to sign the data using RSA-SHA1 Signer before HttprRequest as below :-为了实现这一点,我在HttprRequest之前使用Google Data (GData) APIs使用RSA-SHA1 Signer对数据进行RSA-SHA1 Signer ,如下所示:-

private static PrivateKey getPrivateKey(String consumerKey) {
    try {
        byte[] key = Base64.getDecoder().decode(consumerKey)
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(key)
        KeyFactory kf = KeyFactory.getInstance("RSA")
        return kf.generatePrivate(keySpec)
    } catch (Exception e) {
        throw new RuntimeException(e)
    }
}

import com.google.gdata.client.authn.oauth.OAuthParameters
import com.google.gdata.client.authn.oauth.OAuthRsaSha1Signer
import com.google.gdata.client.authn.oauth.OAuthUtil
import com.google.gdata.client.authn.oauth.RsaSha1PrivateKeyHelper

OAuthRsaSha1Signer rsaSigner = new OAuthRsaSha1Signer()
rsaSigner.setPrivateKey(getPrivateKey(CONSUMER_PRIVATE_KEY))

OAuthParameters params = new OAuthParameters()
params.setOAuthConsumerKey(CONSUMER_KEY)
params.setOAuthNonce(OAuthUtil.getNonce())
params.setOAuthTimestamp(OAuthUtil.getTimestamp())
params.setOAuthSignatureMethod("RSA-SHA1")
params.setOAuthType(OAuthParameters.OAuthType.TWO_LEGGED_OAUTH)
params.setOAuthToken(accessToken)

String paramString = params.getBaseParameters().sort().collect{it}.join('&')

String baseString = [
        OAuthUtil.encode("GET"),
        OAuthUtil.encode('base-url' + 'path'),
        OAuthUtil.encode(paramString)
    ].join('&')

String signature = rsaSigner.getSignature(baseString, params);

params.addCustomBaseParameter("oauth_signature", signature);

//Now calling using HTTPBuilder with signed data
def http = new HTTPBuilder('base-url')

http.request(Method.GET, ContentType.JSON) { req ->
        uri.path = 'path'
        uri.query = params.getBaseParameters()
        response.success = { resp, json ->
            println json
        }
        response.failure = { resp, json -> print json }
    }
}

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

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