Skip to content

Commit

Permalink
exercises client-credentials flow without iStore receipt.
Browse files Browse the repository at this point in the history
antispam token must match auth/resource servers.
assumes http://localhost:8081/c3pro/register and
http://localhost:8081/c3pro/auth
  • Loading branch information
jcschaff committed Dec 4, 2017
1 parent cf32cfa commit 6cac3ac
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 64 deletions.
11 changes: 9 additions & 2 deletions src/main/java/edu/uconn/c3pro/mockmobile/C3proApiDefinition.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package edu.uconn.c3pro.mockmobile;
import com.github.scribejava.core.builder.api.ClientAuthenticationType;
import com.github.scribejava.core.builder.api.DefaultApi20;

public class C3proApiDefinition extends DefaultApi20 {
Expand All @@ -14,14 +15,20 @@ public static C3proApiDefinition instance() {
return InstanceHolder.INSTANCE;
}

@Override
public ClientAuthenticationType getClientAuthenticationType() {
// this is the default for DefaultApi20, but just to make it explicit
return ClientAuthenticationType.HTTP_BASIC_AUTHENTICATION_SCHEME;
}

@Override
public String getAccessTokenEndpoint() {
return "http://localhost:8081/c3pro/oauth";
return "http://localhost:8081/c3pro/auth";
}

@Override
protected String getAuthorizationBaseUrl() {
return "http://localhost:8081/oauth/authorize";
return "http://localhost:8082/oauth/authorize";
}


Expand Down
165 changes: 103 additions & 62 deletions src/main/java/edu/uconn/c3pro/mockmobile/Client.java
Original file line number Diff line number Diff line change
@@ -1,106 +1,147 @@
package edu.uconn.c3pro.mockmobile;

import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

import org.asynchttpclient.DefaultAsyncHttpClientConfig;
import org.hl7.fhir.instance.model.Questionnaire;
import org.asynchttpclient.filter.FilterContext;
import org.asynchttpclient.filter.FilterException;
import org.asynchttpclient.filter.RequestFilter;
//import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.model.OAuth2AccessToken;
import com.github.scribejava.core.model.OAuthRequest;
import com.github.scribejava.core.model.Response;
import com.github.scribejava.core.model.Token;
import com.github.scribejava.core.model.Verb;
import com.github.scribejava.core.oauth.OAuth20Service;
import com.github.scribejava.httpclient.ahc.AhcHttpClient;
import com.github.scribejava.httpclient.ahc.AhcHttpClientConfig;
import com.google.gson.Gson;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.parser.IParser;

public class Client {
private static final String NETWORK_NAME = "Facebook";
private static final String PROTECTED_RESOURCE_URL = "http://localhost:8082/graph.facebook.com/me";
private static final Token EMPTY_TOKEN = null;

public static void main(String[] args) {

try {
// Replace these with your own api key and secret
String apiKey = "your_app_id";
String apiSecret = "your_api_secret";

final AhcHttpClientConfig clientConfig = new AhcHttpClientConfig(new DefaultAsyncHttpClientConfig.Builder()
Gson gson = new Gson();

RequestFilter requestFilter = new RequestFilter() {
@Override
public <T> FilterContext<T> filter(FilterContext<T> arg0) throws FilterException {
System.out.println("intercepting request url "+arg0.getRequest().getUrl());
return arg0;
}
};
//
// must match antispam token in auth/resource database
// (check debug log of auth server for token to add to database)
//
String antispam = "myantispam";

final AhcHttpClientConfig registrationClientConfig = new AhcHttpClientConfig(new DefaultAsyncHttpClientConfig.Builder()
.setMaxConnections(5)
.setRequestTimeout(10000)
.setPooledConnectionIdleTimeout(1000)
.addRequestFilter(requestFilter)
.setReadTimeout(1000)
.setDisableUrlEncodingForBoundRequests(true)
.addRequestFilter(new RequestFilter() {
@Override
public <T> FilterContext<T> filter(FilterContext<T> ctx) throws FilterException {
ctx.getRequest().getHeaders().add("Antispam", antispam);
return ctx;
}
})
.build());

//AhcHttpClient client = new AhcHttpClient(AhcHttpClientConfig.defaultConfig());
AhcHttpClient client = new AhcHttpClient(clientConfig);
String userAgent = "c3pro-java-client/1.0";
Map<String, String> headers = new HashMap<String,String>(){{
put("Antispam", "MY-ANTI-SPAM");
put("Content-Type", "application/json");
put("Accept","application/json");
}};
Gson gson = new Gson();
Registration registration = new Registration(true,"your apple-supplied app purchase receipt");
String registrationJSON = gson.toJson(registration);
String registrationJSON_expected = "{\n" +
" \"sandbox\": true,\n" +
" \"receipt-data\": \"your apple-supplied app purchase receipt\"\n" +
" }";
System.out.println("registrationJSON:\n"+registrationJSON+"\n\nexpected:\n"+registrationJSON_expected+"\n");
byte[] bodyContents = registrationJSON.getBytes("UTF-8");
final String REGISTRATION_URL = "http://localhost:8081/c3pro/register";
Response response = client.execute(userAgent, headers, Verb.POST, REGISTRATION_URL, bodyContents);
String registrationResponseJSON = response.getBody();
RegistrationResponse registrationResponse = gson.fromJson(registrationResponseJSON, RegistrationResponse.class);

/* HTTP/1.1 POST /c3pro/oauth?grant_type=client_credentials
Authentication: Basic BASE64(ClientId:Secret)
NOTE: According to OAuth2 two-legged specifications both clientId and Secret should be x-www-form-urlencoded before Base64 encoding is applied.
Response response = null;
try (AhcHttpClient client = new AhcHttpClient(registrationClientConfig);){
System.out.println("before client.execute(/c3pro/register)");
response = client.execute(userAgent, headers, Verb.POST, REGISTRATION_URL, bodyContents);
System.out.println("after client.execute(/c3pro/register)");
}

String registrationResponseJSON = response.getBody();
RegistrationResponse registrationResponse = gson.fromJson(registrationResponseJSON, RegistrationResponse.class);
System.out.println("registration gotten back from server: "+gson.toJson(registrationResponse));

String urlEncodedClientId = URLEncoder.encode(registrationResponse.getClient_id(),"UTF-8");
String urlEncodedClientSecret = URLEncoder.encode(registrationResponse.getClient_secret(),"UTF-8");

Oauth2 authorization response

//
// manually create the authentication token from client_id and client_secret
// this is not used currently, as the same functionality is embedded in the
//
// String bearerToken = urlEncodedClientId+":"+urlEncodedClientSecret;
// String encodedBearerToken = Base64.getEncoder().encodeToString(bearerToken.getBytes("UTF-8"));
// System.out.println("manual header: 'Basic "+encodedBearerToken);

final AhcHttpClientConfig authorizationClientConfig = new AhcHttpClientConfig(new DefaultAsyncHttpClientConfig.Builder()
.setMaxConnections(5)
.setRequestTimeout(10000)
.setPooledConnectionIdleTimeout(1000)
.addRequestFilter(requestFilter)
.setReadTimeout(1000)
.setDisableUrlEncodingForBoundRequests(true)
.addRequestFilter(new RequestFilter() {
@Override
public <T> FilterContext<T> filter(FilterContext<T> ctx) throws FilterException {
// ctx.getRequest().getHeaders().add("Authorization", "Basic"+ " " + encodedBearerToken);
ctx.getRequest().getHeaders().add("Antispam", antispam);
return ctx;
}
})
.build());

HTTP/1.1 201 Created
Content-Type: application/json
{
"access_token":"{{some token}}",
"expires_in": "{{seconds to expiration}}",
"token_type": "bearer"
}
*/
try (OAuth20Service service = new ServiceBuilder(apiKey)
.apiKey(apiKey)
.apiSecret(apiSecret)
OutputStream debugStream = System.out;
try (OAuth20Service service = new ServiceBuilder(urlEncodedClientId)
.apiKey(urlEncodedClientId)
.apiSecret(urlEncodedClientSecret)
.debug()
.callback("http://localhost:8080/oauth_callback/")
.httpClientConfig(clientConfig)
.debugStream(debugStream)
.httpClientConfig(authorizationClientConfig)
.build(C3proApiDefinition.instance());){
Scanner in = new Scanner(System.in);

System.out.println("before service.getAccessTokenClientCredentialsGrant()");
OAuth2AccessToken accessToken = service.getAccessTokenClientCredentialsGrant();
System.out.println("after service.getAccessTokenClientCredentialsGrant()");


FhirContext ctx = FhirContext.forDstu2();
IParser fhirParser = ctx.newJsonParser();

//
// retrieve questionnaire "q1"
//
final OAuthRequest request = new OAuthRequest(Verb.GET, "https://localhost:8082/c3pro/fhir/Questionnaire/q1");
service.signRequest(accessToken, request);
final Response questionnaireResponse = service.execute(request);
if (questionnaireResponse.getCode() != 200) {
throw new RuntimeException("unexpected return code "+questionnaireResponse.getCode()+" - "+questionnaireResponse.getMessage());
}
final String questionnaireString = response.getBody();
final Questionnaire questionnaire = fhirParser.parseResource(Questionnaire.class, questionnaireString);
System.out.println("received questionnaire: "+fhirParser.encodeResourceToString(questionnaire));
System.out.println("accessToken: "+accessToken.getAccessToken());
System.out.println("refreshToken: "+accessToken.getRefreshToken());
System.out.println("expiresIn: "+accessToken.getExpiresIn());

//
// next, we'll exercise the resource server using the same "service".
//

// FhirContext ctx = FhirContext.forDstu2Hl7Org();
// IParser fhirParser = ctx.newJsonParser();
//
// //
// // retrieve questionnaire "q1"
// //
// final OAuthRequest request = new OAuthRequest(Verb.GET, "https://localhost:8082/c3pro/fhir/Questionnaire/q1");
// service.signRequest(accessToken, request);
// final Response questionnaireResponse = service.execute(request);
// if (questionnaireResponse.getCode() != 200) {
// throw new RuntimeException("unexpected return code "+questionnaireResponse.getCode()+" - "+questionnaireResponse.getMessage());
// }
// final String questionnaireString = response.getBody();
// final Questionnaire questionnaire = fhirParser.parseResource(Questionnaire.class, questionnaireString);
// System.out.println("received questionnaire: "+fhirParser.encodeResourceToString(questionnaire));
}
} catch (Exception e) {
e.printStackTrace();
Expand Down

0 comments on commit 6cac3ac

Please sign in to comment.