Dropwizard、Scribejava、Oauth 2.0 和 Github
Dropwizard, Scribejava, Oauth 2.0 and Github
我正在尝试使用 Dropwizard(我想是 jetty)应用程序中的 scribejava 库通过 oauth 通过 GitHub 进行身份验证。我不太确定自己在做什么,因为我是这一切的新手,但我已经从许多不同的博客和示例中收集了以下资源 class。
@Path("/github")
@Produces(MediaType.APPLICATION_JSON)
public class GithubResource {
private static final Logger LOGGER = LoggerFactory.getLogger(GithubResource.class);
public static final String API_KEY = "APIKEY";
public static final String API_SECRET = "SECRETKEY";
private static final String PROTECTED_RESOURCE_URL = "https://api.github.com/users";
private static final Token EMPTY_TOKEN = null;
@GET
@Produces(MediaType.TEXT_PLAIN)
public Response redirectToAuthorization() {
OAuthService service = createService()
.callback("https://localhost:8443/github/continue")
.build();
String authURL = service.getAuthorizationUrl(EMPTY_TOKEN);
return Response.seeOther(URI.create(authURL)).build();
}
@GET
@Path("continue")
@Produces(MediaType.TEXT_PLAIN)
public Response redirectToApp(@QueryParam("client_id") String oauthToken, @QueryParam("code") String oauthVerifier) {
OAuthService service = createService().build();
Verifier verifier = new Verifier(oauthVerifier);
Token requestToken = service.getAccessToken(EMPTY_TOKEN, verifier);
Token accessToken = service.getAccessToken(requestToken, verifier);
OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service);
service.signRequest(accessToken, request);
com.github.scribejava.core.model.Response response = request.send();
return Response.ok(response.getBody()).build();
}
private ServiceBuilder createService() {
return new ServiceBuilder()
.provider(GitHubApi.class)
.apiKey(API_KEY)
.apiSecret(API_SECRET);
}
}
我花了几天时间才走到这一步,但我现在可以成功地从 github 的响应中提取代码(我认为),但随后应用程序崩溃并显示以下错误日志
ERROR [2015-11-23 03:12:37,417] io.dropwizard.jersey.errors.LoggingExceptionMapper: Error handling a request: fdf48e68be65c626
! com.github.scribejava.core.exceptions.OAuthException: Response body is incorrect. Can't extract a token from this: 'error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&error_uri=https%3A%2F%2Fdeveloper.github.com%2Fv3%2Foauth%2F%23redirect-uri-mismatch2'
! at com.github.scribejava.core.extractors.TokenExtractor20Impl.extract(TokenExtractor20Impl.java:32) ~[scribejava-core-2.0.jar:na]
! at com.github.scribejava.core.oauth.OAuth20ServiceImpl.getAccessToken(OAuth20ServiceImpl.java:37) ~[scribejava-core-2.0.jar:na]
! at org.squandered.generator.resource.GithubResource.redirectToApp(GithubResource.java:58) ~[classes/:na]
! at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_51]
! at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_51]
! at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_51]
! at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_51]
我看到了 "Response body is incorrect. Can't extract a token from this" 但我真的不确定如何才能正确地做到这一点...
有没有人看到我的代码有任何明显的缺陷,或者有将这些库与 oauth 2.0 一起使用的有效示例? Google 似乎 return oauth 1.0 的结果有点不同...
感谢任何正确方向的帮助
干杯
实际上是一个非常简单的错误,我没有从回调方法中的响应 URL 中提取正确的参数。完整的工作示例:
import com.github.scribejava.apis.GitHubApi;
import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.model.OAuthRequest;
import com.github.scribejava.core.model.Token;
import com.github.scribejava.core.model.Verb;
import com.github.scribejava.core.model.Verifier;
import com.github.scribejava.core.oauth.OAuthService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.util.Random;
@Path("/github")
public class GithubResource {
private static final Logger LOGGER = LoggerFactory.getLogger(GithubResource.class);
private static final String PROTECTED_RESOURCE_URL = "https://api.github.com/user";
private static final String API_KEY = "your key";
private static final String API_SECRET = "your secret";
private static final String CALL_BACK_URL = "https://localhost:8443/github/callback/";
private static final Token EMPTY_TOKEN = null;
@GET
public Response getToken() {
OAuthService service = createService().build();
final String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN);
return Response.seeOther(URI.create(authorizationUrl)).build();
}
@GET
@Path("callback")
@Produces(MediaType.TEXT_PLAIN)
public Response callback(@QueryParam("code") String oauthToken) {
OAuthService service = createService().build();
final Verifier verifier = new Verifier(oauthToken);
final Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);
final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service);
service.signRequest(accessToken, request);
final com.github.scribejava.core.model.Response response = request.send();
LOGGER.info("Response code: " + response.getCode());
LOGGER.info("Response body: " + response.getBody());
return Response.ok(response.getBody()).build();
}
private ServiceBuilder createService() {
return new ServiceBuilder()
.provider(GitHubApi.class)
.apiKey(API_KEY)
.apiSecret(API_SECRET)
.scope("repo")
.state("secret" + new Random().nextInt(999_999))
.callback(CALL_BACK_URL);
}
}
我正在尝试使用 Dropwizard(我想是 jetty)应用程序中的 scribejava 库通过 oauth 通过 GitHub 进行身份验证。我不太确定自己在做什么,因为我是这一切的新手,但我已经从许多不同的博客和示例中收集了以下资源 class。
@Path("/github")
@Produces(MediaType.APPLICATION_JSON)
public class GithubResource {
private static final Logger LOGGER = LoggerFactory.getLogger(GithubResource.class);
public static final String API_KEY = "APIKEY";
public static final String API_SECRET = "SECRETKEY";
private static final String PROTECTED_RESOURCE_URL = "https://api.github.com/users";
private static final Token EMPTY_TOKEN = null;
@GET
@Produces(MediaType.TEXT_PLAIN)
public Response redirectToAuthorization() {
OAuthService service = createService()
.callback("https://localhost:8443/github/continue")
.build();
String authURL = service.getAuthorizationUrl(EMPTY_TOKEN);
return Response.seeOther(URI.create(authURL)).build();
}
@GET
@Path("continue")
@Produces(MediaType.TEXT_PLAIN)
public Response redirectToApp(@QueryParam("client_id") String oauthToken, @QueryParam("code") String oauthVerifier) {
OAuthService service = createService().build();
Verifier verifier = new Verifier(oauthVerifier);
Token requestToken = service.getAccessToken(EMPTY_TOKEN, verifier);
Token accessToken = service.getAccessToken(requestToken, verifier);
OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service);
service.signRequest(accessToken, request);
com.github.scribejava.core.model.Response response = request.send();
return Response.ok(response.getBody()).build();
}
private ServiceBuilder createService() {
return new ServiceBuilder()
.provider(GitHubApi.class)
.apiKey(API_KEY)
.apiSecret(API_SECRET);
}
}
我花了几天时间才走到这一步,但我现在可以成功地从 github 的响应中提取代码(我认为),但随后应用程序崩溃并显示以下错误日志
ERROR [2015-11-23 03:12:37,417] io.dropwizard.jersey.errors.LoggingExceptionMapper: Error handling a request: fdf48e68be65c626
! com.github.scribejava.core.exceptions.OAuthException: Response body is incorrect. Can't extract a token from this: 'error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&error_uri=https%3A%2F%2Fdeveloper.github.com%2Fv3%2Foauth%2F%23redirect-uri-mismatch2'
! at com.github.scribejava.core.extractors.TokenExtractor20Impl.extract(TokenExtractor20Impl.java:32) ~[scribejava-core-2.0.jar:na]
! at com.github.scribejava.core.oauth.OAuth20ServiceImpl.getAccessToken(OAuth20ServiceImpl.java:37) ~[scribejava-core-2.0.jar:na]
! at org.squandered.generator.resource.GithubResource.redirectToApp(GithubResource.java:58) ~[classes/:na]
! at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_51]
! at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_51]
! at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_51]
! at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_51]
我看到了 "Response body is incorrect. Can't extract a token from this" 但我真的不确定如何才能正确地做到这一点...
有没有人看到我的代码有任何明显的缺陷,或者有将这些库与 oauth 2.0 一起使用的有效示例? Google 似乎 return oauth 1.0 的结果有点不同...
感谢任何正确方向的帮助
干杯
实际上是一个非常简单的错误,我没有从回调方法中的响应 URL 中提取正确的参数。完整的工作示例:
import com.github.scribejava.apis.GitHubApi;
import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.model.OAuthRequest;
import com.github.scribejava.core.model.Token;
import com.github.scribejava.core.model.Verb;
import com.github.scribejava.core.model.Verifier;
import com.github.scribejava.core.oauth.OAuthService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.util.Random;
@Path("/github")
public class GithubResource {
private static final Logger LOGGER = LoggerFactory.getLogger(GithubResource.class);
private static final String PROTECTED_RESOURCE_URL = "https://api.github.com/user";
private static final String API_KEY = "your key";
private static final String API_SECRET = "your secret";
private static final String CALL_BACK_URL = "https://localhost:8443/github/callback/";
private static final Token EMPTY_TOKEN = null;
@GET
public Response getToken() {
OAuthService service = createService().build();
final String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN);
return Response.seeOther(URI.create(authorizationUrl)).build();
}
@GET
@Path("callback")
@Produces(MediaType.TEXT_PLAIN)
public Response callback(@QueryParam("code") String oauthToken) {
OAuthService service = createService().build();
final Verifier verifier = new Verifier(oauthToken);
final Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);
final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL, service);
service.signRequest(accessToken, request);
final com.github.scribejava.core.model.Response response = request.send();
LOGGER.info("Response code: " + response.getCode());
LOGGER.info("Response body: " + response.getBody());
return Response.ok(response.getBody()).build();
}
private ServiceBuilder createService() {
return new ServiceBuilder()
.provider(GitHubApi.class)
.apiKey(API_KEY)
.apiSecret(API_SECRET)
.scope("repo")
.state("secret" + new Random().nextInt(999_999))
.callback(CALL_BACK_URL);
}
}