added OAuth2 authentication for REST protocol
Change-Id: I3b8f3943ea043587730870a0b861760a4d6f3aa7
diff --git a/protocols/rest/api/BUCK b/protocols/rest/api/BUCK
index 74f33b2..471084f 100644
--- a/protocols/rest/api/BUCK
+++ b/protocols/rest/api/BUCK
@@ -3,6 +3,7 @@
'//utils/rest:onlab-rest',
'//lib:CORE_DEPS',
'//lib:jersey-client',
+ '//lib:jersey-security',
'//lib:jersey-common',
'//lib:httpclient-osgi',
'//lib:httpcore-osgi',
diff --git a/protocols/rest/api/pom.xml b/protocols/rest/api/pom.xml
index ff5f7de..e334e7a 100644
--- a/protocols/rest/api/pom.xml
+++ b/protocols/rest/api/pom.xml
@@ -35,6 +35,12 @@
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.glassfish.jersey.security</groupId>
+ <artifactId>oauth2-client</artifactId>
+ </dependency>
+
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient-osgi</artifactId>
@@ -43,7 +49,6 @@
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
- <version>2.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
diff --git a/protocols/rest/api/src/main/java/org/onosproject/protocol/http/ctl/HttpSBControllerImpl.java b/protocols/rest/api/src/main/java/org/onosproject/protocol/http/ctl/HttpSBControllerImpl.java
index 4a893fcb..602d989 100644
--- a/protocols/rest/api/src/main/java/org/onosproject/protocol/http/ctl/HttpSBControllerImpl.java
+++ b/protocols/rest/api/src/main/java/org/onosproject/protocol/http/ctl/HttpSBControllerImpl.java
@@ -25,10 +25,12 @@
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
+import org.glassfish.jersey.client.oauth2.OAuth2ClientSupport;
import org.onlab.packet.IpAddress;
import org.onosproject.net.DeviceId;
import org.onosproject.protocol.http.HttpSBController;
import org.onosproject.protocol.rest.RestSBDevice;
+import org.onosproject.protocol.rest.RestSBDevice.AuthenticationScheme;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -55,6 +57,8 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
* The implementation of HttpSBController.
*/
@@ -102,11 +106,7 @@
public void addDevice(RestSBDevice device) {
if (!deviceMap.containsKey(device.deviceId())) {
Client client = ignoreSslClient();
- if (device.username() != null) {
- String username = device.username();
- String password = device.password() == null ? "" : device.password();
- authenticate(client, username, password);
- }
+ authenticate(client, device);
clientMap.put(device.deviceId(), client);
deviceMap.put(device.deviceId(), device);
} else {
@@ -283,8 +283,23 @@
}
}
- private void authenticate(Client client, String username, String password) {
- client.register(HttpAuthenticationFeature.basic(username, password));
+ private void authenticate(Client client, RestSBDevice device) {
+ AuthenticationScheme authScheme = device.authentication();
+ if (authScheme == AuthenticationScheme.NO_AUTHENTICATION) {
+ log.debug("{} scheme is specified, ignoring authentication", authScheme);
+ return;
+ } else if (authScheme == AuthenticationScheme.OAUTH2) {
+ String token = checkNotNull(device.token());
+ client.register(OAuth2ClientSupport.feature(token));
+ } else if (authScheme == AuthenticationScheme.BASIC) {
+ String username = device.username();
+ String password = device.password() == null ? "" : device.password();
+ client.register(HttpAuthenticationFeature.basic(username, password));
+ } else {
+ // TODO: Add support for other authentication schemes here.
+ throw new IllegalArgumentException(String.format("Unsupported authentication scheme: %s",
+ authScheme.name()));
+ }
}
protected WebTarget getWebTarget(DeviceId device, String request) {
@@ -343,12 +358,15 @@
try {
sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, new TrustManager[]{new X509TrustManager() {
+ @Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
+ @Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
+ @Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
diff --git a/protocols/rest/api/src/main/java/org/onosproject/protocol/rest/DefaultRestSBDevice.java b/protocols/rest/api/src/main/java/org/onosproject/protocol/rest/DefaultRestSBDevice.java
index 8f59093..fef7f37 100644
--- a/protocols/rest/api/src/main/java/org/onosproject/protocol/rest/DefaultRestSBDevice.java
+++ b/protocols/rest/api/src/main/java/org/onosproject/protocol/rest/DefaultRestSBDevice.java
@@ -41,6 +41,8 @@
private String protocol;
private String url;
private boolean isProxy;
+ private AuthenticationScheme authenticationScheme;
+ private String token;
private final Optional<String> testUrl;
private final Optional<String> manufacturer;
private final Optional<String> hwVersion;
@@ -48,13 +50,13 @@
public DefaultRestSBDevice(IpAddress ip, int port, String name, String password,
String protocol, String url, boolean isActive) {
- this(ip, port, name, password, protocol, url, isActive, "", "", "", "");
+ this(ip, port, name, password, protocol, url, isActive, "", "", "", "", AuthenticationScheme.BASIC, "");
}
public DefaultRestSBDevice(IpAddress ip, int port, String name, String password,
String protocol, String url, boolean isActive, String testUrl, String manufacturer,
- String hwVersion,
- String swVersion) {
+ String hwVersion, String swVersion, AuthenticationScheme authenticationScheme,
+ String token) {
Preconditions.checkNotNull(ip, "IP address cannot be null");
Preconditions.checkArgument(port > 0, "Port address cannot be negative");
Preconditions.checkNotNull(protocol, "protocol address cannot be null");
@@ -65,6 +67,8 @@
this.isActive = isActive;
this.protocol = protocol;
this.url = StringUtils.isEmpty(url) ? null : url;
+ this.authenticationScheme = authenticationScheme;
+ this.token = token;
this.manufacturer = StringUtils.isEmpty(manufacturer) ?
Optional.empty() : Optional.ofNullable(manufacturer);
this.hwVersion = StringUtils.isEmpty(hwVersion) ?
@@ -159,6 +163,16 @@
}
@Override
+ public AuthenticationScheme authentication() {
+ return authenticationScheme;
+ }
+
+ @Override
+ public String token() {
+ return token;
+ }
+
+ @Override
public String toString() {
return MoreObjects.toStringHelper(this)
.omitNullValues()
@@ -168,6 +182,8 @@
.add("username", username)
.add("port", port)
.add("ip", ip)
+ .add("authentication", authenticationScheme.name())
+ .add("token", token)
.add("manufacturer", manufacturer.orElse(null))
.add("hwVersion", hwVersion.orElse(null))
.add("swVersion", swVersion.orElse(null))
diff --git a/protocols/rest/api/src/main/java/org/onosproject/protocol/rest/RestSBDevice.java b/protocols/rest/api/src/main/java/org/onosproject/protocol/rest/RestSBDevice.java
index edcce6e..6767b2d 100644
--- a/protocols/rest/api/src/main/java/org/onosproject/protocol/rest/RestSBDevice.java
+++ b/protocols/rest/api/src/main/java/org/onosproject/protocol/rest/RestSBDevice.java
@@ -26,6 +26,16 @@
*/
public interface RestSBDevice {
/**
+ * REST Authentication schemes.
+ */
+ public enum AuthenticationScheme {
+ NO_AUTHENTICATION,
+ BASIC,
+ OAUTH,
+ OAUTH2,
+ }
+
+ /**
* Returns the ip of this device.
*
* @return ip
@@ -40,6 +50,20 @@
int port();
/**
+ * The authentication scheme of rest device.
+ *
+ * @return authentication
+ */
+ AuthenticationScheme authentication();
+
+ /**
+ * The access token of rest device if authentication is OAuth2.
+ *
+ * @return token
+ */
+ String token();
+
+ /**
* Returns the username of this device.
*
* @return username
@@ -91,6 +115,7 @@
/**
* Returns the proxy state of this device
* (if true, the device is proxying multiple ONOS devices).
+ *
* @return proxy state
*/
boolean isProxy();
@@ -122,4 +147,5 @@
* @return the software version.
*/
Optional<String> swVersion();
+
}