Application Delivery Management
Application Modernization & Connectivity
CyberRes
IT Operations Management
Author: Sureshkumar Thangavel
Library |
Language |
Version |
Description |
google-oauth-client |
Java |
1.20.0 |
For using Oauth2 Implicit Grant |
jackson-core |
Java |
2.5.3 |
For JSON Parsing |
jackson- databind |
Java |
2.5.3 |
For JSON Parsing |
jackson- annotations |
Java |
2.5.3 |
For JSON Parsing |
google-http-client |
Java |
1.20.0 |
For HTTP Headless Client |
google-http-client-jackson2 |
Java |
1.20.0 |
For HTTP Headless Client |
Jose4j |
Java |
0.4.1 |
For OpenID Connect Json Processing and JWT handling |
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
}
defaultConfig {
applicationId "mobile.sample.oauth.nam.netiq.com.nam_aws_sample"
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
compile 'com.amazonaws:aws-android-sdk-cognito:2.2.1'
compile 'com.google.oauth-client:google-oauth-client:1.20.0'
compile 'com.fasterxml.jackson.core:jackson-core:2.5.3'
compile 'com.fasterxml.jackson.core:jackson-databind:2.5.3'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.5.3'
compile 'com.google.http-client:google-http-client:1.20.0'
compile 'com.google.http-client:google-http-client-jackson2:1.20.0'
compile 'org.bitbucket.b_c:jose4j:0.4.1'
}
Client Name: Implicit Sample
Client Type: Native
Redirect URI: x-nam-aws-sample://aws
Grants Required: Implicit
Token Types: ID Token, Access Token
ID Token Signed Response Algorith: RS256
ID Token Encrypted Response Algorithm: None
Leave the rest of the fields empty.
And, you need to automatically append the path and scheme, to match like “https://nam.com/nidp/oauth/nam/.
The following piece of code invokes the metadata by appending “.well-known/openid-configuration” path to the above created url. This is a standard way to get the metadata. This converts the response into a Map with keys mapped to the Keys of Json object returned from metadata url.
private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
/*
* gets resolver object from openid connect metadata for later verification
*/
private VerificationKeyResolver getVerificationKey(Map jsonMetadata) throws IOException, JoseException {
HttpsJwks httpsJwks = new HttpsJwks((String) jsonMetadata.get("jwks_uri"));
List<JsonWebKey> keys = httpsJwks.getJsonWebKeys();
JwksVerificationKeyResolver resolver = new JwksVerificationKeyResolver(keys);
return resolver;
}
/*
* gets openid connect metadata from given well known url. Save the metadata and key
* in a singleton for later access
*/
private Map getOpenIDMetadata(String host) throws IOException, JoseException {
HttpRequest req = HTTP_TRANSPORT.createRequestFactory()
.buildGetRequest(new GenericUrl(host ".well-known/openid-configuration"))
.setParser(new JsonObjectParser(JSON_FACTORY));
HttpResponse resp = req.execute();
Map metadata = resp.parseAs(Map.class);
Singleton.getInstance().setMetadata(metadata);
Singleton.getInstance().setVerificationKey(getVerificationKey(metadata));
return metadata;
}
Using the returned object, you can get the necessary endpoints as below.
String authz_endpoint = (String) jsonMetadata.get("authorization_endpoint");
private String getUrlToLaunch(String host) throws IOException {
Map jsonMetadata = getOpenIDMetadata(host);
String authz_endpoint = (String) jsonMetadata.get("authorization_endpoint");
BrowserClientRequestUrl bc = new BrowserClientRequestUrl(authz_endpoint, Singleton.getInstance().getClientID())
.setResponseTypes(Arrays.asList("token", "id_token"))
.setRedirectUri("x-nam-aws-sample://aws")
.setScopes(Arrays.asList("openid", "email", "profile"))
.set("nonce", new BigInteger(130, new Random()).toString(32))
.setState("/first");
String url = bc.build();
Log.d(LOG_ID, url);
return url;
}
String url = getUrlToLaunch(host);
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(browserIntent);
Intent intent = getIntent();
Uri data = intent.getData();
String id_token = null;
String token = null;
if (data != null && data.getFragment() != null) {
Uri uri = Uri.parse("x-nam-if-sample://test?" data.getFragment()); // convert fragment to query string for easy parsing
id_token = uri.getQueryParameter("id_token");
token = uri.getQueryParameter("access_token");
}
String subject = "unknown";
try {
// https://bitbucket.org/b_c/jose4j/wiki/JWT Examples
JwtConsumer jwtb = new JwtConsumerBuilder()
.setVerificationKeyResolver(Singleton.getInstance().getVerificationKey())
.setExpectedIssuer(false, Singleton.getInstance().getIssuer())
.setExpectedAudience(Singleton.getInstance().getClientID())
.build();
JwtContext jwtc = jwtb.process(idToken);
JwtClaims claims = jwtc.getJwtClaims();
subject = claims.getSubject();
} catch (InvalidJwtException e) {
e.printStackTrace();
} catch (MalformedClaimException e) {
e.printStackTrace();
}
if (subject == null) {
// invalid token
}
String email = null;
try {
String userinfo_endpoint = Singleton.getInstance().getUserInfoEndpoint();
Log.d(LOG_ID, "invoking userinfo with " token ": endpoint " userinfo_endpoint);
HttpResponse resp = HTTP_TRANSPORT.createRequestFactory(new Credential(BearerToken.authorizationHeaderAccessMethod()).setAccessToken(token))
.buildGetRequest(new GenericUrl(userinfo_endpoint))
.setParser(new JsonObjectParser(JSON_FACTORY))
.execute();
Map userinfo = resp.parseAs(Map.class);
email = (String) userinfo.get("email");
Log.d(LOG_ID, "got email " email);
} catch (IOException e) {
e.printStackTrace();
}
String resource_endpoint = “http://weather.com/....”;
HttpResponse resp = HTTP_TRANSPORT.createRequestFactory(new Credential(BearerToken.authorizationHeaderAccessMethod()).setAccessToken(token))
.buildGetRequest(new GenericUrl(resource_endpoint))
.setParser(new JsonObjectParser(JSON_FACTORY))
.execute();