通过TBA连接到NetSuite的问题

时间:2016-10-18 13:35:48

标签: java access-token netsuite

我们正在将我们的SSO集成转换为TBA(与用户名和密码相比)。自从最近的2016.2升级以来,java代码完全无法工作(注意,这在升级之前确实有效)。目前的问题是我们收到403或错误的时间戳错误。与NetSutie合作,我没有看到这些变化的相关性。

我离Java专家很远,所以我希望这里有人可以帮助并告诉我这段代码有什么问题(尽管我能够使用NetSuite PHP工具包让它工作)。

下面是我正在尝试的基本代码(大多数是从我们的Java开发人员处获得的,我正在尝试解决此问题),我自己使用NetSuite的想法进行了略微调整。

public class Main{
public static void main(String[]args){
    String compID="compID";
    String consumerKey="consumerKey";
    String consumerSecret="consumerSecret";
    String tokenId="tokenId";
    String tokenSecret="tokenSecret";
    String restletURL="https://rest.sandbox.netsuite.com/app/site/hosting/restlet.nl?script=123&deploy=2";

    Token token=new Token(tokenId,tokenSecret);
    String nonce=RandomStringUtils.randomNumeric(9);
    long ms=new java.util.Date().getTime();
    ms=(long)Math.floor(ms/1000);
    String time=ms+"";

    String baseString=compID+"&"+consumerKey+"&"+tokenId+"&"+nonce+"&"+time;
    String key=consumerSecret+"&"+tokenSecret;
    byte[] bytes=key.getBytes();
    SecretKeySpec secretkey=new SecretKeySpec(bytes,"HmacSHA1");
    Mac keymac=null;
    try{
        keymac=Mac.getInstance("HmacSHA1");
        keymac.init(secretkey);
    }catch(NoSuchAlgorithmException e){
        e.printStackTrace();
    }catch(InvalidKeyException e){
        e.printStackTrace();
    }
    byte[] hash=keymac.doFinal(baseString.getBytes());
    String result=new String(Base64.encodeBase64(hash,false));
    String oauth_timestamp = Instant.now().toEpochMilli()+"";

    String headerAuthorization="OAuth realm=\""+compID+"\", oauth_consumer_key=\""+consumerKey+"\", oauth_token=\""+token+"\", oauth_nonce=\""+nonce+"\", oauth_timestamp=\""+oauth_timestamp+"\", oauth_signature_method=\"HMAC-SHA1\", oauth_version=\"1.0\", oauth_signature=\""+result+"\"";

    System.out.println(headerAuthorization);

    HttpClient httpclient=HttpClientBuilder.create().build();

    HttpGet request=new HttpGet(restletURL);
    request.setHeader(HttpHeaders.AUTHORIZATION,headerAuthorization);

    String response="";
    try{
        //Handle the response from NetSuite
        ResponseHandler<String> responseHandler=new ResponseHandler<String>(){
            @Override
            public String handleResponse(final HttpResponse response)throws ClientProtocolException,IOException{
                int status=response.getStatusLine().getStatusCode();

                //If the call is successful
                if(status>=200 && status<300){
                    HttpEntity entity=response.getEntity();
                    return entity!=null?EntityUtils.toString(entity):null;
                }else{
                    throw new ClientProtocolException("Unexpected response status: "+status);
                }
            }
        };
        response=httpclient.execute(request,responseHandler);
        System.out.println(response);
    }catch(Exception e){
        e.printStackTrace();
    }
  }
}

1 个答案:

答案 0 :(得分:0)

我们终于有了这个工作。原来,NetSuite改变了他们的API工作方式(根据他们告诉我的情况,至少)。要实现此目的,需要 Scribe 1.3.7 Maven Repo)。然后你需要两个Java文件:

<强> DummyService.java

import org.scribe.builder.api.DefaultApi10a;
import org.scribe.model.Token;

public class DummyService extends DefaultApi10a{
  @Override
  public String getAccessTokenEndpoint() {
    // TODO Auto-generated method stub
    return null;
  }
  @Override
  public String getAuthorizationUrl(Token arg0) {
    // TODO Auto-generated method stub
    return null;
  }
  @Override
  public String getRequestTokenEndpoint() {
    // TODO Auto-generated method stub
    return null;
  }
}

<强> TokenAuth.java

import org.scribe.builder.ServiceBuilder;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.SignatureType;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.oauth.OAuthService;

public class TokenAuth{
  private static final String TOKEN_ID="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
  private static final String TOKEN_SECRET="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
  private static final String CONSUMER_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
  private static final String CONSUMER_SECRET="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
  private static final String REALM="123456";
  private static final String CONTENT_TYPE="content-type";
  private static final String APP_JSON="application/json";

  private static final String REST_URL="https://rest.sandbox.netsuite.com/app/site/hosting/restlet.nl?script=xxx&deploy=x";
  private static final String JSON_PAYLOD="{}";

  private static OAuthService service=getService();
  private static Token accessToken=getToken();
  public static void main(String[]args){
    Response responseGet=callWithHttpGet();
    System.out.println(responseGet.getBody());  
    Response responsePost=callWithHttpPost();
    System.out.println(responsePost.getBody());
  }
  private static Response callWithHttpGet(){
    OAuthRequest request=new OAuthRequest(Verb.GET,REST_URL);
    request.setRealm(REALM);
    service.signRequest(accessToken,request);
    return request.send();
  }
  private static Response callWithHttpPost(){
    OAuthRequest request=new OAuthRequest(Verb.POST,REST_URL);
    request.setRealm(REALM);
    request.addHeader(CONTENT_TYPE,APP_JSON);
    request.addPayload(JSON_PAYLOD);
    service.signRequest(accessToken,request);
    return request.send();
  }
  private static Token getToken(){
    return new Token(TOKEN_ID, TOKEN_SECRET);
  }
  private static OAuthService getService(){
    return new ServiceBuilder().provider(DummyService.class).apiKey(CONSUMER_KEY).apiSecret(CONSUMER_SECRET).signatureType(SignatureType.Header).build();
  }
}

*注意:此数据现已在SuiteAnswers文章中更新(Scribe 1.3.7的要求除外)(42167 - Java > RESTlet Authentication using Token (Token-Based Authentication)