Skip to content

Commit

Permalink
Merge pull request #10 from sengopal/master
Browse files Browse the repository at this point in the history
Adding documentation for id token grant
  • Loading branch information
sonamrks committed Nov 20, 2018
2 parents 1d07f2a + 3460553 commit 217b309
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 7 deletions.
11 changes: 10 additions & 1 deletion README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ image:https://codecov.io/gh/eBay/ebay-oauth-java-client/branch/master/graph/badg

image:https://img.shields.io/github/license/eBay/ebay-oauth-java-client.svg["GitHub license",link="https://github.com/eBay/ebay-oauth-java-client/blob/master/LICENSE"]


eBay OAuth client library is a simple and easy-to-use library for integrating with eBay OAuth and designed to be used for OAuth 2.0 specification supported by eBay. There are multiple standard clients that can be used with eBay OAuth, such as Spring OAuth client. However, this library in addition to functioning as a simple eBay OAuth client, helps with additional features such as cached App tokens. There are also future enhancements planned to add id_token support, 'login with eBay' support etc.,

== What is OAuth 2.0
Expand Down Expand Up @@ -67,6 +66,16 @@ Read more about this grant type at https://developer.ebay.com/api-docs/static/oa
=== Grant Type: Refresh Token
This grant type can be performed by simply using `OAuth2Api.getAccessToken()`. Usually access tokens are short lived and if the access token is expired, the caller can use the refresh token to generate a new access token. Read more about it at https://developer.ebay.com/api-docs/static/oauth-qref-auth-code-grant.html[Using a refresh token to update a user access token]

=== Grant Type: Id Token (OpenID Connect)
This grant type is added to support the OpenID connect protocol for generating an *Id token* which helps provide identity federation without any API access. This protocol is usually helpful when a functionality such as "Login via eBay" is required without any need for access tokens.

This is a two step process. The URL to redirect the user can be generated via `OAuth2Api.generateIdTokenUrl()`. Once the user authenticates to eBay site, the callback redirect URL will be invoked with the id_token as an additional parameter. The validity of the `id_token` can be verified and the verified attributes extracted using `EbayIdTokenValidator.validate()`. Ensure that only the authorized clientIds are passed to the function to verify if the id_token has been issued to one of those clients only.

This method also verifies the signature, the expiration and issuer of the `id_token` before returning back the verified attributes.

NOTE: It is also a good practice to send a unique nonce in every request and verify if the id_token has been issued only for that nonce.


== Contribution
Contributions in terms of patches, features, or comments are always welcome. Refer to link:CONTRIBUTING.adoc[CONTRIBUTING] for guidelines. Submit Github issues for any feature enhancements, bugs, or documentation problems as well as questions and comments.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,8 @@
import static org.junit.Assert.*;

public class AuthorizationCodeTest {
private static final List<String> SCOPE_LIST = Arrays.asList(new String[]{"https://api.ebay.com/oauth/api_scope", "https://api.ebay.com/oauth/api_scope/sell.marketing.readonly"});
private static final List<String> authorizationScopesList = Arrays.asList(new String[]{"https://api.ebay.com/oauth/api_scope", "https://api.ebay.com/oauth/api_scope/sell.marketing.readonly"});

private static final List<String> SCOPE_LIST = Arrays.asList("https://api.ebay.com/oauth/api_scope", "https://api.ebay.com/oauth/api_scope/sell.marketing.readonly");
private static final List<String> authorizationScopesList = Arrays.asList("https://api.ebay.com/oauth/api_scope", "https://api.ebay.com/oauth/api_scope/sell.marketing.readonly");

//NOTE: Change this env to Environment.PRODUCTION to run this test in PRODUCTION
private static final Environment EXECUTION_ENV = Environment.SANDBOX;
Expand Down Expand Up @@ -88,7 +87,10 @@ public void testExchangeAuthorizationCode() throws InterruptedException, IOExcep
OAuthResponse oauth2Response = auth2Api.exchangeCodeForAccessToken(EXECUTION_ENV, authorizationCode);
assertNotNull(oauth2Response);

assertTrue(oauth2Response.getRefreshToken().isPresent());
assertNotNull(oauth2Response.getRefreshToken().get());

assertTrue(oauth2Response.getAccessToken().isPresent());
assertNotNull(oauth2Response.getAccessToken().get());
assertNull(oauth2Response.getErrorMessage());
System.out.println("Token Exchange Completed\n" + oauth2Response);
Expand All @@ -110,6 +112,7 @@ public void testExchangeRefreshForAccessToken() throws InterruptedException, IOE
if (authorizationCode != null) {
OAuth2Api oauth2Api = new OAuth2Api();
OAuthResponse oauth2Response = oauth2Api.exchangeCodeForAccessToken(EXECUTION_ENV, authorizationCode);
assertTrue(oauth2Response.getRefreshToken().isPresent());
refreshToken = oauth2Response.getRefreshToken().get().getToken();
}
assertNotNull(refreshToken);
Expand All @@ -118,8 +121,11 @@ public void testExchangeRefreshForAccessToken() throws InterruptedException, IOE
OAuthResponse accessTokenResponse = oauth2Api.getAccessToken(EXECUTION_ENV, refreshToken, SCOPE_LIST);
assertNotNull(accessTokenResponse);

assertTrue(accessTokenResponse.getAccessToken().isPresent());
assertNotNull(accessTokenResponse.getAccessToken().get());
assertNull(accessTokenResponse.getErrorMessage());

assertTrue(accessTokenResponse.getRefreshToken().isPresent());
assertNull(accessTokenResponse.getRefreshToken().get().getToken());
System.out.println("Refresh To Access Completed\n" + accessTokenResponse);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public static Map<String, Map<String, String>> loadUserCredentials() {
Map<String, Map<String, String>> values = new HashMap<>();

if (runtimeParam != null && !runtimeParam.trim().isEmpty()) {
System.out.println("Using User Runtime Parameter: " + runtimeParam);
// System.out.println("Using User Runtime Parameter: " + runtimeParam);
isUserCredentialsLoaded = true;
return new Yaml().load(runtimeParam);
} else {
Expand All @@ -79,7 +79,7 @@ private static String getRuntimeParam(String varName) {
// Trying from Env Variable instead
propertyValue = System.getenv(varName);
}
System.out.println("Extracted value: " + propertyValue);
// System.out.println("Extracted value: " + propertyValue);
return propertyValue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
Expand Down Expand Up @@ -110,8 +111,17 @@ public String getIdTokenResponseUrl(String nonce) throws InterruptedException {
WebElement password = driver.findElement(By.cssSelector("input[type='password']"));
userId.sendKeys(CRED_USERNAME);
password.sendKeys(CRED_PASSWORD);
driver.findElement(By.name("sgnBt")).submit();
WebElement sgnBt = null;
try {
sgnBt = driver.findElement(By.name("sgnBt"));
} catch (NoSuchElementException e) {
// ignore exception
}
if (sgnBt == null) {
sgnBt = driver.findElement(By.id("sgnBt"));
}

sgnBt.submit();
Thread.sleep(5000);

String url = null;
Expand Down

0 comments on commit 217b309

Please sign in to comment.