Skip to content
Permalink
Browse files
Promote the OAuth v2 API
  • Loading branch information
nacx committed Apr 15, 2015
2 parents 21a422b + 2a12587 commit 1c8b7764f66f3bbbaa9aaf52a548ebc7e9dd5361
Show file tree
Hide file tree
Showing 22 changed files with 1,418 additions and 0 deletions.
@@ -0,0 +1,16 @@
In order to use oauth applications must specify the following properties:

Mandatory:
<myprovider>.identity - the oauth identity (e.g., service account email in Google Api's)
<myprovider>.credential - the private key used to sign requests, in pem format
oauth.endpoint - the endpoint to use for authentication (e.g., "http://accounts.google.com/o/oauth2/token" in Google Api's)
oauth.audience - the "audience" of the token request (e.g., "http://accounts.google.com/o/oauth2/token" in Google Api's)

Running the live test:

mvn clean install -Plive\
-Dtest.oauth.identity=<accout email>\
-Dtest.oauth.credential=<accout pk in pem format>\
-Dtest.oauth.endpoint=https://accounts.google.com/o/oauth2/token\
-Dtest.jclouds.oauth.audience=https://accounts.google.com/o/oauth2/token\
-Dtest.jclouds.oauth.scope=https://www.googleapis.com/auth/prediction
@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.jclouds.labs</groupId>
<artifactId>jclouds-labs-google</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>

<!-- TODO: when out of labs, switch to org.jclouds.api -->
<groupId>org.apache.jclouds.labs</groupId>
<artifactId>oauth</artifactId>
<name>jclouds OAuth core</name>
<description>jclouds components to access OAuth</description>

<properties>
<test.oauth.identity>FIX_ME</test.oauth.identity>
<test.oauth.credential>FIX_ME</test.oauth.credential>
<test.oauth.endpoint>FIX_ME</test.oauth.endpoint>
<test.jclouds.oauth.audience>FIX_ME</test.jclouds.oauth.audience>
<test.jclouds.oauth.scope>FIX_ME</test.jclouds.oauth.scope>
<test.oauth.api-version>2</test.oauth.api-version>
<test.oauth.build-version />
</properties>

<dependencies>
<dependency>
<groupId>org.apache.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${jclouds.version}</version>
</dependency>
<dependency>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${jclouds.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.jclouds.driver</groupId>
<artifactId>jclouds-slf4j</artifactId>
<version>${jclouds.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>mockwebserver</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>live</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>default-test</id>
<configuration>
<skipTests>true</skipTests>
</configuration>
</execution>
<execution>
<id>integration</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<systemPropertyVariables>
<test.oauth.identity>${test.oauth.identity}</test.oauth.identity>
<test.oauth.credential>${test.oauth.credential}</test.oauth.credential>
<test.oauth.endpoint>${test.oauth.endpoint}</test.oauth.endpoint>
<test.oauth.api-version>${test.oauth.api-version}</test.oauth.api-version>
<test.oauth.build-version>${test.oauth.build-version}</test.oauth.build-version>
<test.jclouds.oauth.jws-alg>${test.jclouds.oauth.jws-alg}</test.jclouds.oauth.jws-alg>
<test.jclouds.oauth.audience>${test.jclouds.oauth.audience}</test.jclouds.oauth.audience>
<test.jclouds.oauth.scope>${test.jclouds.oauth.scope}</test.jclouds.oauth.scope>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.oauth.v2;

import static javax.ws.rs.core.MediaType.APPLICATION_JSON;

import java.io.Closeable;

import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;

import org.jclouds.oauth.v2.functions.ClaimsToAssertion;
import org.jclouds.oauth.v2.config.Authorization;
import org.jclouds.oauth.v2.domain.Claims;
import org.jclouds.oauth.v2.domain.Token;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.ParamParser;

/**
* Binds to an OAuth2 <a href="http://tools.ietf.org/html/rfc6749#section-3.1">authorization endpoint</a>.
*/
@Endpoint(Authorization.class)
public interface AuthorizationApi extends Closeable {
@Named("oauth2:authorize")
@POST
@FormParams(keys = "grant_type", values = "urn:ietf:params:oauth:grant-type:jwt-bearer")
@Consumes(APPLICATION_JSON)
Token authorize(@FormParam("assertion") @ParamParser(ClaimsToAssertion.class) Claims claims);
}
@@ -0,0 +1,30 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.oauth.v2.config;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.inject.Qualifier;

@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Qualifier
public @interface Authorization {
}
@@ -0,0 +1,38 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.oauth.v2.config;

import static com.google.common.base.CaseFormat.LOWER_CAMEL;
import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
import static com.google.common.base.Preconditions.checkNotNull;

/** Defines the contents of the credential field in {@link org.jclouds.ContextBuilder#credentials(String, String)}. */
public enum CredentialType {

BEARER_TOKEN_CREDENTIALS,

/** Contents are a PEM-encoded P12 Private Key. */
P12_PRIVATE_KEY_CREDENTIALS;

@Override public String toString() {
return UPPER_UNDERSCORE.to(LOWER_CAMEL, name());
}

public static CredentialType fromValue(String credentialType) {
return valueOf(LOWER_CAMEL.to(UPPER_UNDERSCORE, checkNotNull(credentialType, "credentialType")));
}
}
@@ -0,0 +1,83 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.oauth.v2.config;

import static org.jclouds.oauth.v2.config.CredentialType.P12_PRIVATE_KEY_CREDENTIALS;
import static org.jclouds.oauth.v2.config.OAuthProperties.CREDENTIAL_TYPE;
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;

import java.net.URI;
import java.security.PrivateKey;

import javax.inject.Named;
import javax.inject.Singleton;

import org.jclouds.oauth.v2.AuthorizationApi;
import org.jclouds.oauth.v2.filters.BearerTokenFromCredentials;
import org.jclouds.oauth.v2.filters.JWTBearerTokenFlow;
import org.jclouds.oauth.v2.filters.OAuthFilter;

import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Provides;
import com.google.inject.TypeLiteral;

public final class OAuthModule extends AbstractModule {

@Override protected void configure() {
bindHttpApi(binder(), AuthorizationApi.class);
bind(CredentialType.class).toProvider(CredentialTypeFromPropertyOrDefault.class);
bind(new TypeLiteral<Supplier<PrivateKey>>() {}).annotatedWith(Authorization.class).to(PrivateKeySupplier.class);
}

@Provides
@Authorization
protected Supplier<URI> oauthEndpoint(@javax.inject.Named("oauth.endpoint") String endpoint) {
return Suppliers.ofInstance(URI.create(endpoint));
}

@Singleton
public static class CredentialTypeFromPropertyOrDefault implements Provider<CredentialType> {
@Inject(optional = true)
@Named(CREDENTIAL_TYPE)
String credentialType = P12_PRIVATE_KEY_CREDENTIALS.toString();

@Override
public CredentialType get() {
return CredentialType.fromValue(credentialType);
}
}

@Provides
@Singleton
protected OAuthFilter authenticationFilterForCredentialType(CredentialType credentialType,
JWTBearerTokenFlow serviceAccountAuth,
BearerTokenFromCredentials bearerTokenAuth) {
switch (credentialType) {
case P12_PRIVATE_KEY_CREDENTIALS:
return serviceAccountAuth;
case BEARER_TOKEN_CREDENTIALS:
return bearerTokenAuth;
default:
throw new IllegalArgumentException("Unsupported credential type: " + credentialType);
}
}

}
@@ -0,0 +1,41 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.oauth.v2.config;

public final class OAuthProperties {

/** The JSON Web Signature alg, must be {@code RS256} or {@code none}. */
public static final String JWS_ALG = "jclouds.oauth.jws-alg";

/**
* The oauth audience, who this token is intended for. For instance in JWT and for
* google API's this property maps to: {"aud","https://accounts.google.com/o/oauth2/token"}
*
* @see <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-30">doc</a>
*/
public static final String AUDIENCE = "jclouds.oauth.audience";

/**
* Specify if credentials are id + private key or if you are reusing an oauth2 token.
*
* @see org.jclouds.oauth.v2.config.CredentialType
*/
public static final String CREDENTIAL_TYPE = "jclouds.oauth.credential-type";

private OAuthProperties() {
}
}

0 comments on commit 1c8b776

Please sign in to comment.