在jclouds中为GoogleAPI手动认证,分离token获取
Manual authentication for Google API in jclouds, separating token acquisition
我需要将身份验证阶段与 Google 的 Api 创建分开,但(对我而言)很难做到这一点。
这非常重要,因为我正在创建一个 REST API,出于安全原因,它应该接收先前获得的授权令牌,而不是直接从其用户那里接收凭据,因为有了令牌,我可以将生命周期限制设置为在 RFC 6750.
中指定
我有以下代码:
public class Main {
public static void main(String[] args) {
// Reads the JSON credential file provided by Google
String jsonContent = readJson(args[1]);
// Pass the credential content
GoogleComputeEngineApi googleApi =
createApi(jsonContent);
}
public static GoogleComputeEngineApi createApi(final String jsonCredentialContent) {
try {
Supplier<Credentials> credentialSupplier = new GoogleCredentialsFromJson(
jsonCredentialContent);
ComputeServiceContext context = ContextBuilder
.newBuilder("google-compute-engine")
.credentialsSupplier(credentialSupplier)
.buildView(ComputeServiceContext.class);
Credentials credentials = credentialSupplier.get();
ContextBuilder contextBuilder = ContextBuilder
.newBuilder(GoogleComputeEngineProviderMetadata.builder()
.build())
.credentials(credentials.identity, credentials.credential);
Injector injector = contextBuilder.buildInjector();
return injector.getInstance(GoogleComputeEngineApi.class);
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
return null;
}
}
}
下面是我需要的假代码:
public class Main {
public static void main(String[] args) {
String jsonCredentialContent = readJson(args[1]);
String oauthToken = "";
// First acquires the OAuth token
if(getAuthenticationType("google-compute-engine").equals("oauth")) {
oauthToken = getTokenForOAuth(jsonCredentialContent);
}
// Creates the Api with the previously acquired token
GoogleComputeEngineApi googleApi =
createApi(oauthToken);
}
[...]
}
可以直接使用jclouds OAuthAPI获取bearer token,如下:
GoogleCredentialsFromJson credentials = new GoogleCredentialsFromJson(jsoncreds);
AuthorizationApi oauth = ContextBuilder.newBuilder("google-compute-engine")
.credentialsSupplier(credentials)
.buildApi(AuthorizationApi.class);
try {
long nowInSeconds = System.currentTimeMillis() / 1000;
Claims claims = Claims.create(
credentials.get().identity, // issuer
"https://www.googleapis.com/auth/compute", // write scope
"https://accounts.google.com/o/oauth2/token", // audience
nowInSeconds + 60, // token expiration (seconds)
nowInSeconds // current time (secods)
);
Token token = oauth.authorize(claims);
System.out.println(token);
} finally {
oauth.close();
}
获得 Bearer 访问令牌后,您可以使用它创建 jclouds 上下文,如下所示:
// Override GCE default Oauth flow (JWT) by the Bearer token flow
Properties overrides = new Properties();
overrides.put(OAuthProperties.CREDENTIAL_TYPE, CredentialType.BEARER_TOKEN_CREDENTIALS.toString());
// It is important to set the proper identity too, as it is used to resolve the GCE project
ComputeServiceContext ctx = ContextBuilder.newBuilder("google-compute-engine")
.overrides(overrides)
.credentials(credentials.get().identity, token.accessToken())
.buildView(ComputeServiceContext.class);
GoogleComputeEngineApi google = ctx.unwrapApi(GoogleComputeEngineApi.class);
我需要将身份验证阶段与 Google 的 Api 创建分开,但(对我而言)很难做到这一点。
这非常重要,因为我正在创建一个 REST API,出于安全原因,它应该接收先前获得的授权令牌,而不是直接从其用户那里接收凭据,因为有了令牌,我可以将生命周期限制设置为在 RFC 6750.
中指定我有以下代码:
public class Main {
public static void main(String[] args) {
// Reads the JSON credential file provided by Google
String jsonContent = readJson(args[1]);
// Pass the credential content
GoogleComputeEngineApi googleApi =
createApi(jsonContent);
}
public static GoogleComputeEngineApi createApi(final String jsonCredentialContent) {
try {
Supplier<Credentials> credentialSupplier = new GoogleCredentialsFromJson(
jsonCredentialContent);
ComputeServiceContext context = ContextBuilder
.newBuilder("google-compute-engine")
.credentialsSupplier(credentialSupplier)
.buildView(ComputeServiceContext.class);
Credentials credentials = credentialSupplier.get();
ContextBuilder contextBuilder = ContextBuilder
.newBuilder(GoogleComputeEngineProviderMetadata.builder()
.build())
.credentials(credentials.identity, credentials.credential);
Injector injector = contextBuilder.buildInjector();
return injector.getInstance(GoogleComputeEngineApi.class);
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
return null;
}
}
}
下面是我需要的假代码:
public class Main {
public static void main(String[] args) {
String jsonCredentialContent = readJson(args[1]);
String oauthToken = "";
// First acquires the OAuth token
if(getAuthenticationType("google-compute-engine").equals("oauth")) {
oauthToken = getTokenForOAuth(jsonCredentialContent);
}
// Creates the Api with the previously acquired token
GoogleComputeEngineApi googleApi =
createApi(oauthToken);
}
[...]
}
可以直接使用jclouds OAuthAPI获取bearer token,如下:
GoogleCredentialsFromJson credentials = new GoogleCredentialsFromJson(jsoncreds);
AuthorizationApi oauth = ContextBuilder.newBuilder("google-compute-engine")
.credentialsSupplier(credentials)
.buildApi(AuthorizationApi.class);
try {
long nowInSeconds = System.currentTimeMillis() / 1000;
Claims claims = Claims.create(
credentials.get().identity, // issuer
"https://www.googleapis.com/auth/compute", // write scope
"https://accounts.google.com/o/oauth2/token", // audience
nowInSeconds + 60, // token expiration (seconds)
nowInSeconds // current time (secods)
);
Token token = oauth.authorize(claims);
System.out.println(token);
} finally {
oauth.close();
}
获得 Bearer 访问令牌后,您可以使用它创建 jclouds 上下文,如下所示:
// Override GCE default Oauth flow (JWT) by the Bearer token flow
Properties overrides = new Properties();
overrides.put(OAuthProperties.CREDENTIAL_TYPE, CredentialType.BEARER_TOKEN_CREDENTIALS.toString());
// It is important to set the proper identity too, as it is used to resolve the GCE project
ComputeServiceContext ctx = ContextBuilder.newBuilder("google-compute-engine")
.overrides(overrides)
.credentials(credentials.get().identity, token.accessToken())
.buildView(ComputeServiceContext.class);
GoogleComputeEngineApi google = ctx.unwrapApi(GoogleComputeEngineApi.class);