我们正在将我们的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();
}
}
}
答案 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))