2016-09-16 4 views
1

Я хочу получить данные с помощью JIRA REST api с предоставленным сервисом JIRA OAuth authentication.Groovy - интеграция Jira OAuth с использованием HttpBuilder

В основном я могу достичь этой задачи, используя ScribeJava с Groovy. Но я хочу, чтобы отделить весь процесс, как показано ниже: -

  • запрос, чтобы получить запрос маркера
  • Запрос авторизироваться URL-адрес
  • Запрос на маркер доступа
  • запрос, чтобы получить фактические данные, используя HTTPBuilder

Таким образом, я могу достичь вышеупомянутых первых трех шагов, используя ScribeJava и сохраняя accessToken в Database для дальнейшего r Equest данных, как показано ниже: -

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) 
    } 

Сейчас я строю 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. 

Так все выше вещи я в состоянии достигнуть выше трех шагов и хранения маркера доступа в db для будущего запроса только для data.

Итак, чтобы достичь 4-й шаг к получению фактических данных с использованием HTTPBuilder я делаю некоторые вещи, как показано ниже: -

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 } 
     } 
    } 

Но я получаю ответ, как: -

{oauth_problem=signature_method_rejected} 

Итак, может ли кто-нибудь предложить мне, как я могу получить фактические данные с использованием HTTPBuilder с использованием аутентификации OAuth с использованием accessToken и secretToken?

Примечание: - Я могу получить фактические данные, а также с помощью ScribeJava Апи с OAuthRequest, но требование, чтобы получить фактические данные, используя HTTPBuilder

Я просто хочу указатель, как ее достичь.

ответ

0

После долгих поисков у меня есть решение from here. На самом деле HTTPBuilder внутренне используя Signpost который подписывающего запрос с использованием HmacSha Signer в то время как Jira rest api поддерживает RSA-SHA1 Signer для проверки HttpRequest, поэтому это дает ответ, как: -

{oauth_problem=signature_method_rejected} 

Таким образом, в основном я должен сделать заказ RSA-SHA1 Signer, чтобы получить подпись на запрос HTTP , Для того чтобы достигнуть этого я использую Google Data (GData) APIs подписать данные, используя RSA-SHA1 Signer до того HttprRequest, как показано ниже: -

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 } 
    } 
}