Skip to content

Commit

Permalink
[REST-4] Added support for OAuth 2.0 Bearer Token Authentication usin…
Browse files Browse the repository at this point in the history
…g Client ID & Client Secret
  • Loading branch information
Matteo Alessandroni committed May 22, 2018
1 parent bd07243 commit e585404
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,64 @@ public void setPassword(GuardedString password) {
this.password = password;
}

private String bearer;
private String clientId;

@ConfigurationProperty(displayMessageKey = "bearer.display",
helpMessageKey = "bearer.help", order = 2)
public String getBearer() {
return bearer;
@ConfigurationProperty(displayMessageKey = "clientId.display",
helpMessageKey = "clientId.help", order = 2)
public String getCliendId() {
return clientId;
}

public void setBearer(final String bearer) {
this.bearer = bearer;
public void setCliendId(final String clientId) {
this.clientId = clientId;
}

private String clientSecret;

@ConfigurationProperty(displayMessageKey = "clientSecret.display",
helpMessageKey = "clientSecret.help", order = 3)
public String getClientSecret() {
return clientSecret;
}

public void setClientSecret(final String clientSecret) {
this.clientSecret = clientSecret;
}

private String accessTokenNodeId;

@ConfigurationProperty(displayMessageKey = "accessTokenNodeId.display",
helpMessageKey = "accessTokenNodeId.help", order = 4)
public String getAccessTokenNodeId() {
return accessTokenNodeId;
}

public void setAccessTokenNodeId(final String accessTokenNodeId) {
this.accessTokenNodeId = accessTokenNodeId;
}

private String accessTokenBaseAddress;

@ConfigurationProperty(displayMessageKey = "accessTokenBaseAddress.display",
helpMessageKey = "accessTokenBaseAddress.help", order = 5)
public String getAccessTokenBaseAddress() {
return accessTokenBaseAddress;
}

public void setAccessTokenBaseAddress(final String accessTokenBaseAddress) {
this.accessTokenBaseAddress = accessTokenBaseAddress;
}

private String accessTokenContentType = MediaType.APPLICATION_FORM_URLENCODED;

@ConfigurationProperty(displayMessageKey = "accessTokenContentType.display",
helpMessageKey = "accessTokenContentType.help", order = 6)
public String getAccessTokenContentType() {
return accessTokenContentType;
}

public void setAccessTokenContentType(final String accessTokenContentType) {
this.accessTokenContentType = accessTokenContentType;
}

@Override
Expand Down
54 changes: 52 additions & 2 deletions src/main/java/net/tirasa/connid/bundles/rest/RESTConnector.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@
*/
package net.tirasa.connid.bundles.rest;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import net.tirasa.connid.commons.scripted.AbstractScriptedConnector;
import net.tirasa.connid.commons.scripted.Constants;
import org.apache.cxf.jaxrs.client.WebClient;
import org.identityconnectors.common.StringUtil;
import org.identityconnectors.common.security.SecurityUtil;
import org.identityconnectors.framework.common.exceptions.ConnectorException;
import org.identityconnectors.framework.common.objects.ObjectClass;
import org.identityconnectors.framework.common.objects.OperationOptions;
import org.identityconnectors.framework.common.objects.filter.FilterTranslator;
Expand All @@ -44,13 +49,58 @@ public void init(final Configuration cfg) {
null).
accept(config.getAccept()).
type(config.getContentType());
if (config.getBearer() != null) {
this.client.header(HttpHeaders.AUTHORIZATION, "Bearer " + config.getBearer());
if (StringUtil.isNotBlank(config.getCliendId())
&& StringUtil.isNotBlank(config.getClientSecret())
&& StringUtil.isNotBlank(config.getAccessTokenBaseAddress())
&& StringUtil.isNotBlank(config.getAccessTokenNodeId())) {
this.client = WebClient.create(config.getBaseAddress())
.type(config.getAccept())
.accept(config.getContentType());
this.client.header(HttpHeaders.AUTHORIZATION, "Bearer " + generateToken());
} else {
this.client = WebClient.create(config.getBaseAddress(),
null,
config.getUsername(),
config.getPassword() == null ? null : SecurityUtil.decrypt(config.getPassword()),
null)
.type(config.getAccept())
.accept(config.getContentType());
}

super.init(cfg);
}

private String generateToken() {
WebClient webClient = WebClient
.create(config.getAccessTokenBaseAddress())
.type(config.getAccessTokenContentType())
.accept(config.getAccept());

String contentUri = new StringBuilder("&client_id=")
.append(config.getCliendId())
.append("&client_secret=")
.append(config.getClientSecret())
.append("&username=")
.append(config.getUsername())
.append("&password=")
.append(SecurityUtil.decrypt(config.getPassword()))
.toString();
String token = null;
try {
Response response = webClient.post(contentUri);
String responseAsString = response.readEntity(String.class);
JsonNode result = new ObjectMapper().readTree(responseAsString);
if (result == null || !result.hasNonNull(config.getAccessTokenNodeId())) {
throw new ConnectorException("No access token found - " + responseAsString);
}
token = result.get(config.getAccessTokenNodeId()).textValue();
} catch (Exception ex) {
throw new ConnectorException("While obtaining authentication token", ex);
}

return token;
}

@Override
protected Map<String, Object> buildArguments() {
final Map<String, Object> arguments = new HashMap<String, Object>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,14 @@
#

rest.connector.display=REST Connector

baseAddress.display=Base address of the target RESTful service
accept.display=Value for the HTTP Accept header; defaults to application/json
contentType.display=Value for the HTTP Content-Type header; defaults to application/json
username.display=Username for authentication to the target RESTful service
password.display=Password for authentication to the target RESTful service
clientId.display=Client id for authentication to the target RESTful service
clientSecret.display=Client secret for authentication to the target RESTful service
accessTokenBaseAddress.display=Base address of the target RESTful service used to obtain access token
accessTokenContentType.display=Value for the HTTP Content-Type header for the target Access Token RESTful service; defaults to application/x-www-form-urlencoded
accessTokenNodeId.display=Field id of the JSON object node, returned from target Access Token RESTful service, that contains token value
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,14 @@
#

rest.connector.display=Connettore REST

baseAddress.display=Indirizzo base del servizio REST che si vuole utilizzare
accept.display=Valore del campo HTTP Accept header; di default \u00e8 application/json
contentType.display=Valore del campo HTTP Content-Type header; di default \u00e8 application/json
username.display=Username per l'autenticazione al servizio REST in questione
password.display=Password per l'autenticazione al servizio REST in questione
clientId.display=Client id per l'autenticazione al servizio REST in questione
clientSecret.display=Client secret per l'autenticazione al servizio REST in questione
accessTokenBaseAddress.display=Indirizzo base del servizio REST che si vuole utilizzare per ottenere il token
accessTokenContentType.display=Valore del campo HTTP Content-Type header per il servizio REST per ottenere il token; di default \u00e8 application/x-www-form-urlencoded
accessTokenNodeId.display=Identificatore del campo del nodo JSON, ritornato dal servizio REST per ottenere il token, dove \u00e8 salvato il valore del token

0 comments on commit e585404

Please sign in to comment.