java - que - spring oauth ejemplo
¿Cómo crear una solicitud de oAuth usando java? (2)
Necesito hacer una conexión con el sitio web de Viagogo usando oAuth. En referencia a su documentación , necesito crear una solicitud similar a la siguiente
Using the example in step 1A, this means you may generate a signature base string that looks like the following:
GET&http%3A%2F%2Fapi.viagogo.net%2FPublic%2FSimpleOAuthAccessRequest&oauth_consumer_key%3Dtestkey%26oauth_nonce%3Dmyn0nc3%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1292404912%26oauth_version%3D1.0%26scope%3DAPI.Public
Estoy usando el siguiente código, pero cuando comento las líneas 1, 2 devuelvo un error no autorizado , y cuando los uso muestra que oauthService.signRequest devuelve vacío.
TradeKingAPI.java
import org.scribe.builder.api.DefaultApi10a;
import org.scribe.model.Token;
public class TradeKingAPI extends DefaultApi10a {
@Override
public String getRequestTokenEndpoint() {
return "http://api.viagogo.net/Public/SimpleOAuthAccessRequest";
}
@Override
public String getAccessTokenEndpoint() {
return "http://api.viagogo.net/Public/SimpleOAuthAccessRequest";
}
@Override
public String getAuthorizationUrl(Token requestToken) {
return "http://api.viagogo.net/Public/SimpleOAuthAccessRequest";
}
}
main.java
import org.scribe.builder.ServiceBuilder;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.oauth.OAuthService;
import api.TradeKingAPI;
import org.scribe.builder.api.DefaultApi10a;
import org.scribe.model.OAuthConstants;
import org.scribe.oauth.OAuthService;
........
OAuthService oauthService = new ServiceBuilder()
.provider(TradeKingAPI.class)
.apiKey("My consumer key")
.apiSecret("My secret")
.scope("API.Public")
.build();
Long seconds = (System.currentTimeMillis() / 1000);
System.out.println(">>>" + seconds);
String stSeconds = seconds.toString();
OAuthRequest request = new OAuthRequest(Verb.GET, "http://api.viagogo.net/Public
/SimpleOAuthAccessRequest");
request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, "My consumer key");
request.addOAuthParameter(OAuthConstants.NONCE, "myn0nc3");
request.addOAuthParameter(OAuthConstants.SIGN_METHOD, "HMAC-SHA1");
request.addOAuthParameter(OAuthConstants.TIMESTAMP, seconds.toString());
request.addOAuthParameter(OAuthConstants.VERSION, "1.0");
request.addOAuthParameter("scope", "API.Public");
1 String signature = oauthService.signRequest(OAuthConstants.EMPTY_TOKEN, request);
2 request.addOAuthParameter(OAuthConstants.SIGNATURE,signature);
Response response = request.send();
System.err.println(">>" + response.isSuccessful());
System.err.println(">>" + response.getMessage());
System.err.println(">>" + response.getBody());
Supongo que está tratando de obtener el token de acceso (por ejemplo, está llamando a SimpleOAuthAccessRequest). OauthService de Scribe tiene métodos para manejar esto.
PERO ... si vas a hacerlo manualmente, aquí está lo que está mal con tu código, al menos con lo que has enumerado aquí. Supongo que has configurado a escriba correctamente.
- no pase el secreto del consumidor con su solicitud, solo para firmar la solicitud
- deberías usar addOauthParameter vs addQueryStringParameter
- deberías usar las constantes de Scribe
- debe firmar la solicitud (de nuevo, OauthService de Scribe tiene un método de ayuda para firmar la solicitud)
Aquí está el fragmento de código actualizado.
ACTUALIZACIÓN: haz que Scribe te proporcione todos los parámetros de Oauth
OAuthRequest request = new OAuthRequest(Verb.GET, ...
//since you''re just passing Oauth parameters and nothing else,
//you can use signRequest will create Oauth Parameters for you
service.signRequest(OAuthConstants.EMPTY_TOKEN, request)
Response response = request.send()
Según lo que entiendo de la documentación pública de acceso API de Viagogo, el token que obtienes en el paso 1 es equivalente a un token de solicitud en un "baile" completo de OAuth 1.0a.
Por lo tanto, debería poder usar las clases internas de scribe-java para obtener este token sin hacerlo manualmente. La única diferencia es que en Scribe, esta solicitud también envía una url de devolución de llamada al servidor de OAuth para el siguiente paso de OAuth "dance".
Como no puedo obtener una cuenta de consumidor, solo puedo hacer una suposición aquí. Entonces, tengamos 2 escenarios:
Escenario 1: el servidor Viagogo tolera parámetros adicionales (es decir, URL de devolución de llamada)
para que pueda ir con este código
import org.scribe.builder.api.DefaultApi10a;
import org.scribe.model.Token;
public class TradeKingAPI extends DefaultApi10a {
@Override
public Verb getRequestTokenVerb()
{
return Verb.GET;
}
@Override
public String getRequestTokenEndpoint() {
return "http://api.viagogo.net/Public/SimpleOAuthAccessRequest";
}
@Override
public String getAccessTokenEndpoint() {
return "none";
}
@Override
public String getAuthorizationUrl(Token requestToken) {
return "none";
}
}
Entonces su código de llamada será:
OAuthService service = new ServiceBuilder()
.provider(TradeKingAPI.class)
.signatureType(QueryString)
.apiKey("My consumer key")
.apiSecret("My secret")
.scope("API.Public")
.build();
Token requestToken = service.getRequestToken();
//make your API calls
OAuthRequest request = new OAuthRequest(Verb.GET,
"http://api.viagogo.net/Public/Event/235");
service.signRequest(requestToken, request);
Response response = request.send();
System.out.println(response.getBody());
Pero como dije, si la seguridad de Viagogo es un poco estricta y rechaza el inútil param oauth_callback
, tendrá que cambiar al escenario 2
Escenario 2: construya su propio OAuthService
En este escenario, debe crear un nuevo OAuthService
para evitar el tratamiento del parámetro OAuthCallback
.
import org.scribe.builder.api.DefaultApi10a;
import org.scribe.model.*;
import org.scribe.oauth.OAuth10aServiceImpl;
import java.util.Map;
public class OAuth10aServiceForViagogo extends OAuth10aServiceImpl {
private OAuthConfig config;
private DefaultApi10a api;
public OAuth10aServiceForViagogo(DefaultApi10a api, OAuthConfig config) {
super(api, config);
this.api = api;
this.config = config;
}
private void addOAuthParams(OAuthRequest request, Token token) {
request.addOAuthParameter(OAuthConstants.TIMESTAMP, api.getTimestampService().getTimestampInSeconds());
request.addOAuthParameter(OAuthConstants.NONCE, api.getTimestampService().getNonce());
request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, config.getApiKey());
request.addOAuthParameter(OAuthConstants.SIGN_METHOD, api.getSignatureService().getSignatureMethod());
request.addOAuthParameter(OAuthConstants.VERSION, getVersion());
request.addOAuthParameter(OAuthConstants.SCOPE, config.getScope());
request.addOAuthParameter(OAuthConstants.SIGNATURE, getSignature(request, token));
}
private String getSignature(OAuthRequest request, Token token) {
String baseString = api.getBaseStringExtractor().extract(request);
String signature = api.getSignatureService().getSignature(baseString, config.getApiSecret(), token.getSecret());
return signature;
}
private void appendSignature(OAuthRequest request) {
for (Map.Entry<String, String> entry : request.getOauthParameters().entrySet()) {
request.addQuerystringParameter(entry.getKey(), entry.getValue());
}
}
@Override
public Token getRequestToken(RequestTuner tuner) {
OAuthRequest request = new OAuthRequest(api.getRequestTokenVerb(), api.getRequestTokenEndpoint());
addOAuthParams(request, OAuthConstants.EMPTY_TOKEN);
appendSignature(request);
Response response = request.send(tuner);
String body = response.getBody();
return api.getRequestTokenExtractor().extract(body);
}
}
TrakingApi
clase TrakingApi
será ligeramente diferente para crear un OAuth10aServiceForViagogo
al llamar a createService
:
import org.scribe.builder.api.DefaultApi10a;
import org.scribe.model.Token;
public class TradeKingAPI extends DefaultApi10a {
@override
public OAuthService createService(OAuthConfig config)
{
return new OAuth10aServiceForViagogo(this, config);
}
@Override
public Verb getRequestTokenVerb()
{
return Verb.GET;
}
@Override
public String getRequestTokenEndpoint() {
return "http://api.viagogo.net/Public/SimpleOAuthAccessRequest";
}
@Override
public String getAccessTokenEndpoint() {
return "none";
}
@Override
public String getAuthorizationUrl(Token requestToken) {
return "none";
}
}
Entonces su código de llamada será el mismo:
OAuthService service = new ServiceBuilder()
.provider(TradeKingAPI.class)
.signatureType(QueryString)
.apiKey("My consumer key")
.apiSecret("My secret")
.scope("API.Public")
.build();
Token requestToken = service.getRequestToken();
//make your API calls
OAuthRequest request = new OAuthRequest(Verb.GET,
"http://api.viagogo.net/Public/Event/235");
service.signRequest(requestToken, request);
Response response = request.send();
System.out.println(response.getBody());
No probé todo este código porque no puedo acceder a la clave de consumidor y la clave secreta, pero debe estar cerca de lo que necesita.