Skip to content

Commit

Permalink
Initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
imesh committed Nov 9, 2017
0 parents commit 2b4a475
Show file tree
Hide file tree
Showing 10 changed files with 490 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.class
*.iml
.idea/
target/
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# WSO2 OAuth Mediator

WSO2 OAuth mediator can be used for generating OAuth2 tokens for talking to service endpoints
secured with OAuth2 protocol in WSO2 ESB/Integrator and API Manager. Currently, it only supports
password grant type and it can be extended to incorporate other grant types as required.

## Getting Started

1. Clone this project:

````
git clone https://github.com/imesh/wso2-oauth-meditor
cd wso2-oauth-mediator/
````

2. Build OAuth Mediator using Maven:

````
mvn clean install
````

3. Copy OAuth mediator JAR file to the following folder in the WSO2 server:

````
[WSO2-SERVER-HOME]/repository/components/lib/
````

4. Use the following sequence to engage the OAuth mediator in the in message flow:

````xml
<sequence xmlns="http://ws.apache.org/ns/synapse" name="oauth-sequence2">
<class name = "org.wso2.apim.mediators.oauth.OAuthMediator"></class>
</sequence>
````

# License

This source code is licensed under Apache 2.0.
94 changes: 94 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.wso2.apim</groupId>
<artifactId>wso2-oauth-mediator</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

<repositories>
<repository>
<id>wso2-nexus</id>
<name>WSO2 internal Repository</name>
<url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
<checksumPolicy>ignore</checksumPolicy>
</releases>
</repository>

<repository>
<id>wso2.releases</id>
<name>WSO2 internal Repository</name>
<url>http://maven.wso2.org/nexus/content/repositories/releases/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
<checksumPolicy>ignore</checksumPolicy>
</releases>
</repository>

<repository>
<id>wso2.snapshots</id>
<name>Apache Snapshot Repository</name>
<url>http://maven.wso2.org/nexus/content/repositories/snapshots/</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>

<repository>
<id>central</id>
<name>Maven Central Repository</name>
<layout>default</layout>
<url>http://repo1.maven.org/maven2</url>
<releases>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
<checksumPolicy>ignore</checksumPolicy>
</releases>
</repository>
</repositories>

<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.synapse</groupId>
<artifactId>synapse-core</artifactId>
<version>2.1.7-wso2v15</version>
</dependency>
</dependencies>
</project>
49 changes: 49 additions & 0 deletions src/main/java/org/wso2/apim/mediators/oauth/OAuthMediator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Licensed 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.wso2.apim.mediators.oauth;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.MessageContext;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.apache.synapse.mediators.AbstractMediator;
import org.wso2.apim.mediators.oauth.client.TokenCache;
import org.wso2.apim.mediators.oauth.client.TokenGeneratorScheduledExecutor;

import java.util.Map;

/**
* OAuth mediator for generating OAuth tokens for invoking service endpoints secured with OAuth2.
*/
public class OAuthMediator extends AbstractMediator {

private static final Log log = LogFactory.getLog(OAuthMediator.class);

static {
// Initialize oauth client token generator
new TokenGeneratorScheduledExecutor().init();
}

@Override
public boolean mediate(MessageContext messageContext) {
log.debug("---> OAuth mediator invoked");
String accessToken = TokenCache.getInstance().getTokenMap().get("AccessToken");
Map<String,Object> transportHeaders = (Map<String, Object>) ((Axis2MessageContext)messageContext)
.getAxis2MessageContext().getProperty("TRANSPORT_HEADERS");
transportHeaders.put("Authorization", "Bearer " + accessToken);
log.debug("---> Access token set: " + accessToken);
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Licensed 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.wso2.apim.mediators.oauth.client;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.apim.mediators.oauth.client.domain.TokenResponse;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Base64;

/**
* OAuth client implementation.
*/
public class OAuthClient {

private static final Log log = LogFactory.getLog(OAuthClient.class);

private static final String UTF_8 = "UTF-8";
private static final String HTTP_POST = "POST";
private static final String AUTHORIZATION_HEADER = "Authorization";
private static final String CONTENT_TYPE_HEADER = "Content-Type";
private static final String APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded";

private static final Gson gson = new GsonBuilder().create();

/**
* Generate OAuth token using password grant type.
* @param url token endpoint URL
* @param apiKey api consumer key
* @param apiSecret api consumer secret
* @param username username
* @param password password
* @return
* @throws IOException
*/
public static TokenResponse generateToken(String url, String apiKey, String apiSecret,
String username, String password)
throws IOException {

if(log.isDebugEnabled()) {
log.debug("Initializing token generation request: [token-endpoint] " + url);
}

// Set query parameters
String query = String.format("grant_type=password&username=%s&password=%s",
URLEncoder.encode(username, UTF_8), URLEncoder.encode(password, UTF_8));
url += "?" + query;
URL url_ = new URL(url);
HttpURLConnection connection = (HttpURLConnection) url_.openConnection();
connection.setDoOutput(true);

// Set HTTP method
connection.setRequestMethod(HTTP_POST);

// Set authorization header
String credentials = Base64.getEncoder().encodeToString((apiKey + ":" + apiSecret).getBytes());
connection.setRequestProperty(AUTHORIZATION_HEADER, "Basic " + credentials);
connection.setRequestProperty(CONTENT_TYPE_HEADER, APPLICATION_X_WWW_FORM_URLENCODED);

// Make HTTP request
log.debug("Requesting access token...");

int responseCode = connection.getResponseCode();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();

if(log.isDebugEnabled()) {
log.debug("Response: [status-code] " + responseCode + " [message] " + response.toString());
}
return gson.fromJson(response.toString(), TokenResponse.class);
}
}
51 changes: 51 additions & 0 deletions src/main/java/org/wso2/apim/mediators/oauth/client/TokenCache.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Licensed 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.wso2.apim.mediators.oauth.client;

import java.util.HashMap;
import java.util.Map;

/**
* Token cache implementation.
*/
public class TokenCache {

private static final TokenCache instance = new TokenCache();

private final Map<String, String> tokenMap = new HashMap<>();

/**
* Private constructor.
*/
private TokenCache() {

}

/**
* Get token cache instance.
* @return
*/
public static TokenCache getInstance() {
return instance;
}

/**
* Get token map.
* @return
*/
public Map<String, String> getTokenMap() {
return tokenMap;
}
}
Loading

0 comments on commit 2b4a475

Please sign in to comment.