mirror of
https://repository.entgra.net/community/device-mgt-plugins.git
synced 2025-09-16 23:42:15 +00:00
changed device access verification approach
This commit is contained in:
parent
93ed31c584
commit
bfb9c62968
@ -24,23 +24,10 @@ function onRequest(context) {
|
||||
var constants = require("/app/modules/constants.js");
|
||||
|
||||
var websocketEndpoint = devicemgtProps["wssURL"].replace("https", "wss");
|
||||
var jwtService = carbonServer.osgiService(
|
||||
'org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService');
|
||||
var jwtClient = jwtService.getJWTClient();
|
||||
var encodedClientKeys = session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS"]);
|
||||
if (encodedClientKeys) {
|
||||
var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"];
|
||||
var resp = tokenUtil.decode(encodedClientKeys).split(":");
|
||||
var deviceParam = "{\"scope\":\"stats\",\"deviceIdentifiers\":[{\"id\":\"" + device.deviceIdentifier
|
||||
+ "\", \"type\":\"" + device.type + "\"}]}";
|
||||
var encodedScope = tokenUtil.encode(deviceParam);
|
||||
var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username,"default",
|
||||
{"device": encodedScope});
|
||||
var token = "";
|
||||
var tokenPair = session.get(constants["TOKEN_PAIR"]);
|
||||
if (tokenPair) {
|
||||
token = tokenPair.accessToken;
|
||||
}
|
||||
websocketEndpoint = websocketEndpoint + "/secured-outputui/org.wso2.iot.android.sense/1.0.0?" +
|
||||
var token = parse(tokenPair)["accessToken"];
|
||||
websocketEndpoint = websocketEndpoint + "/secured-websocket/org.wso2.iot.android.sense/1.0.0?" +
|
||||
"token="+ token +"&deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type;
|
||||
}
|
||||
return {"device": device, "websocketEndpoint": websocketEndpoint};
|
||||
|
||||
@ -229,7 +229,7 @@ public class ArduinoServiceImpl implements ArduinoService {
|
||||
ArduinoConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true);
|
||||
}
|
||||
JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
|
||||
String scopes = "arduino_device cdmf/" + ArduinoConstants.DEVICE_TYPE + "/" + deviceId;
|
||||
String scopes = " device_" + deviceId;
|
||||
AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
|
||||
apiApplicationKey.getConsumerSecret(), owner, scopes);
|
||||
//create token
|
||||
|
||||
@ -18,30 +18,17 @@
|
||||
|
||||
function onRequest(context) {
|
||||
var log = new Log("stats.js");
|
||||
var carbonServer = require("carbon").server;
|
||||
var device = context.unit.params.device;
|
||||
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var constants = require("/app/modules/constants.js");
|
||||
|
||||
var websocketEndpoint = devicemgtProps["wssURL"].replace("https", "wss");
|
||||
var jwtService = carbonServer.osgiService(
|
||||
'org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService');
|
||||
var jwtClient = jwtService.getJWTClient();
|
||||
var encodedClientKeys = session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS"]);
|
||||
if (encodedClientKeys) {
|
||||
var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"];
|
||||
var resp = tokenUtil.decode(encodedClientKeys).split(":");
|
||||
var deviceParam = "{\"scope\":\"stats\",\"deviceIdentifiers\":[{\"id\":\"" + device.deviceIdentifier
|
||||
+ "\", \"type\":\"" + device.type + "\"}]}";
|
||||
var encodedScope = tokenUtil.encode(deviceParam);
|
||||
var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username,"default",
|
||||
{"device": encodedScope});
|
||||
var token = "";
|
||||
var tokenPair = session.get(constants["TOKEN_PAIR"]);
|
||||
if (tokenPair) {
|
||||
token = tokenPair.accessToken;
|
||||
}
|
||||
websocketEndpoint = websocketEndpoint + "/secured-outputui/org.wso2.iot.devices.temperature/1.0.0?" +
|
||||
var token = parse(tokenPair)["accessToken"];
|
||||
websocketEndpoint = websocketEndpoint + "/secured-websocket/org.wso2.iot.devices.temperature/1.0.0?" +
|
||||
"token="+ token +"&deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type;
|
||||
}
|
||||
|
||||
return {"device": device, "websocketEndpoint": websocketEndpoint};
|
||||
}
|
||||
@ -213,7 +213,7 @@ public class RaspberryPiServiceImpl implements RaspberryPiService {
|
||||
RaspberrypiConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true);
|
||||
}
|
||||
JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
|
||||
String scopes = "cdmf/" + RaspberrypiConstants.DEVICE_TYPE + "/" + deviceId;
|
||||
String scopes = " device_" + deviceId;
|
||||
AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
|
||||
apiApplicationKey.getConsumerSecret(), owner, scopes);
|
||||
//create token
|
||||
|
||||
@ -18,30 +18,17 @@
|
||||
|
||||
function onRequest(context) {
|
||||
var log = new Log("stats.js");
|
||||
var carbonServer = require("carbon").server;
|
||||
var device = context.unit.params.device;
|
||||
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var constants = require("/app/modules/constants.js");
|
||||
|
||||
var websocketEndpoint = devicemgtProps["wssURL"].replace("https", "wss");
|
||||
var jwtService = carbonServer.osgiService(
|
||||
'org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService');
|
||||
var jwtClient = jwtService.getJWTClient();
|
||||
var encodedClientKeys = session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS"]);
|
||||
if (encodedClientKeys) {
|
||||
var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"];
|
||||
var resp = tokenUtil.decode(encodedClientKeys).split(":");
|
||||
var deviceParam = "{\"scope\":\"stats\",\"deviceIdentifiers\":[{\"id\":\"" + device.deviceIdentifier
|
||||
+ "\", \"type\":\"" + device.type + "\"}]}";
|
||||
var encodedScope = tokenUtil.encode(deviceParam);
|
||||
var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username,"default",
|
||||
{"device": encodedScope});
|
||||
var token = "";
|
||||
var tokenPair = session.get(constants["TOKEN_PAIR"]);
|
||||
if (tokenPair) {
|
||||
token = tokenPair.accessToken;
|
||||
}
|
||||
websocketEndpoint = websocketEndpoint + "/secured-outputui/org.wso2.iot.devices.temperature/1.0.0?" +
|
||||
var token = parse(tokenPair)["accessToken"];
|
||||
websocketEndpoint = websocketEndpoint + "/secured-websocket/org.wso2.iot.devices.temperature/1.0.0?" +
|
||||
"token="+ token +"&deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type;
|
||||
}
|
||||
|
||||
return {"device": device, "websocketEndpoint": websocketEndpoint};
|
||||
}
|
||||
@ -312,13 +312,10 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
|
||||
VirtualFireAlarmConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true);
|
||||
}
|
||||
JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
|
||||
String device = "{ \"scope\":\"mqtt-publisher mqtt-subscriber\", \"deviceIdentifiers\":[{\"id\":\""+deviceId+"\", " +
|
||||
"\"type\":\""+VirtualFireAlarmConstants.DEVICE_TYPE+"\"}]}";
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("device", Base64.encodeBase64String(device.getBytes()));
|
||||
String scopes = " device_" + deviceId;
|
||||
AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
|
||||
apiApplicationKey.getConsumerSecret(), owner,
|
||||
null, params);
|
||||
scopes);
|
||||
String accessToken = accessTokenInfo.getAccessToken();
|
||||
String refreshToken = accessTokenInfo.getRefreshToken();
|
||||
XmppAccount newXmppAccount = new XmppAccount();
|
||||
|
||||
@ -24,24 +24,13 @@ function onRequest(context) {
|
||||
var constants = require("/app/modules/constants.js");
|
||||
|
||||
var websocketEndpoint = devicemgtProps["wssURL"].replace("https", "wss");
|
||||
var jwtService = carbonServer.osgiService(
|
||||
'org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService');
|
||||
var jwtClient = jwtService.getJWTClient();
|
||||
var encodedClientKeys = session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS"]);
|
||||
if (encodedClientKeys) {
|
||||
var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"];
|
||||
var resp = tokenUtil.decode(encodedClientKeys).split(":");
|
||||
var deviceParam = "{\"scope\":\"stats\",\"deviceIdentifiers\":[{\"id\":\"" + device.deviceIdentifier
|
||||
+ "\", \"type\":\"" + device.type + "\"}]}";
|
||||
var encodedScope = tokenUtil.encode(deviceParam);
|
||||
var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username,"default",
|
||||
{"device": encodedScope});
|
||||
var token = "";
|
||||
|
||||
var tokenPair = session.get(constants["TOKEN_PAIR"]);
|
||||
if (tokenPair) {
|
||||
token = tokenPair.accessToken;
|
||||
}
|
||||
websocketEndpoint = websocketEndpoint + "/secured-outputui/org.wso2.iot.devices.temperature/1.0.0?" +
|
||||
var token = parse(tokenPair)["accessToken"];
|
||||
websocketEndpoint = websocketEndpoint + "/secured-websocket/org.wso2.iot.devices.temperature/1.0.0?" +
|
||||
"token=" + token + "&deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type;
|
||||
}
|
||||
|
||||
return {"device": device, "websocketEndpoint": websocketEndpoint};
|
||||
}
|
||||
@ -58,6 +58,6 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>secured-outputui</finalName>
|
||||
<finalName>secured-websocket</finalName>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@ -79,6 +79,22 @@
|
||||
<groupId>commons-pool.wso2</groupId>
|
||||
<artifactId>commons-pool</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-jaxrs</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-gson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>jsr311-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@ -147,9 +163,18 @@
|
||||
org.wso2.carbon.identity.oauth2.stub,
|
||||
org.wso2.carbon.identity.oauth2.stub.dto,
|
||||
org.wso2.carbon.user.api,
|
||||
org.wso2.carbon.utils.multitenancy
|
||||
org.wso2.carbon.utils.multitenancy,
|
||||
feign,
|
||||
feign.auth,
|
||||
feign.codec,
|
||||
feign.gson,
|
||||
javax.cache
|
||||
</Import-Package>
|
||||
<DynamicImport-Package>*</DynamicImport-Package>
|
||||
<Embed-Dependency>
|
||||
jsr311-api,
|
||||
feign-jaxrs
|
||||
</Embed-Dependency>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
@ -17,19 +17,52 @@
|
||||
*/
|
||||
package org.wso2.carbon.device.mgt.output.adapter.websocket.authorization;
|
||||
|
||||
import feign.Feign;
|
||||
import feign.FeignException;
|
||||
import feign.gson.GsonDecoder;
|
||||
import feign.gson.GsonEncoder;
|
||||
import feign.jaxrs.JAXRSContract;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.authentication.AuthenticationInfo;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.constants.WebsocketConstants;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.OAuthRequestInterceptor;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto.AuthorizationRequest;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto
|
||||
.DeviceAccessAuthorizationAdminService;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto.DeviceAuthorizationResult;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto.DeviceIdentifier;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.config.Properties;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.config.Property;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.config.WebsocketConfig;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.util.WebSocketSessionRequest;
|
||||
|
||||
import javax.websocket.Session;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This authorizer crossvalidates the request with device id and device type.
|
||||
*/
|
||||
public class DeviceAuthorizer implements Authorizer {
|
||||
private static final String STATS_SCOPE_IDENTIFIER = "stats";
|
||||
private static final String DEVICE_MGT_SCOPE_IDENTIFIER = "device-mgt";
|
||||
|
||||
private static DeviceAccessAuthorizationAdminService deviceAccessAuthorizationAdminService;
|
||||
private static final String CDMF_SERVER_BASE_CONTEXT = "/api/device-mgt/v1.0";
|
||||
private static final String DEVICE_MGT_SERVER_URL = "deviceMgtServerUrl";
|
||||
private static final String STAT_PERMISSION = "statsPermission";
|
||||
private static Log logger = LogFactory.getLog(DeviceAuthorizer.class);
|
||||
private static List<String> statPermissions;
|
||||
|
||||
public DeviceAuthorizer() {
|
||||
Properties properties =
|
||||
WebsocketConfig.getInstance().getWebsocketValidationConfigs().getAuthorizer().getProperties();
|
||||
statPermissions = getPermissions(properties);
|
||||
deviceAccessAuthorizationAdminService = Feign.builder()
|
||||
.requestInterceptor(new OAuthRequestInterceptor())
|
||||
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
|
||||
.target(DeviceAccessAuthorizationAdminService.class, getDeviceMgtServerUrl(properties)
|
||||
+ CDMF_SERVER_BASE_CONTEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuthorized(AuthenticationInfo authenticationInfo, Session session, String stream) {
|
||||
@ -37,19 +70,59 @@ public class DeviceAuthorizer implements Authorizer {
|
||||
Map<String, String> queryParams = webSocketSessionRequest.getQueryParamValuePairs();
|
||||
String deviceId = queryParams.get("deviceId");
|
||||
String deviceType = queryParams.get("deviceType");
|
||||
Object scopeObject = authenticationInfo.getProperties().get(WebsocketConstants.SCOPE_IDENTIFIER);
|
||||
|
||||
if (deviceId != null && !deviceId.isEmpty() && deviceType != null && !deviceType.isEmpty()
|
||||
&& scopeObject != null) {
|
||||
String scopes[] = (String[]) scopeObject;
|
||||
String requiredScope = DEVICE_MGT_SCOPE_IDENTIFIER + ":" + deviceType + ":" + deviceId + ":"
|
||||
+ STATS_SCOPE_IDENTIFIER;
|
||||
for (String scope : scopes) {
|
||||
if (requiredScope.equals(scope)) {
|
||||
if (deviceId != null && !deviceId.isEmpty() && deviceType != null && !deviceType.isEmpty()) {
|
||||
|
||||
AuthorizationRequest authorizationRequest = new AuthorizationRequest();
|
||||
authorizationRequest.setTenantDomain(authenticationInfo.getTenantDomain());
|
||||
if (statPermissions != null && !statPermissions.isEmpty()) {
|
||||
authorizationRequest.setPermissions(statPermissions);
|
||||
}
|
||||
authorizationRequest.setUsername(authenticationInfo.getUsername());
|
||||
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
|
||||
deviceIdentifier.setId(deviceId);
|
||||
deviceIdentifier.setType(deviceType);
|
||||
List<DeviceIdentifier> deviceIdentifiers = new ArrayList<>();
|
||||
deviceIdentifiers.add(deviceIdentifier);
|
||||
authorizationRequest.setDeviceIdentifiers(deviceIdentifiers);
|
||||
try {
|
||||
DeviceAuthorizationResult deviceAuthorizationResult =
|
||||
deviceAccessAuthorizationAdminService.isAuthorized(authorizationRequest);
|
||||
List<DeviceIdentifier> devices = deviceAuthorizationResult.getAuthorizedDevices();
|
||||
if (devices != null && devices.size() > 0) {
|
||||
DeviceIdentifier authorizedDevice = devices.get(0);
|
||||
if (authorizedDevice.getId().equals(deviceId) && authorizedDevice.getType().equals(deviceType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (FeignException e) {
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getDeviceMgtServerUrl(Properties properties) {
|
||||
String deviceMgtServerUrl = null;
|
||||
for (Property property : properties.getProperty()) {
|
||||
if (property.getName().equals(DEVICE_MGT_SERVER_URL)) {
|
||||
deviceMgtServerUrl = property.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (deviceMgtServerUrl == null && deviceMgtServerUrl.isEmpty()) {
|
||||
logger.error("deviceMgtServerUrl can't be empty ");
|
||||
}
|
||||
return deviceMgtServerUrl;
|
||||
}
|
||||
|
||||
private List<String> getPermissions(Properties properties) {
|
||||
List<String> permission = new ArrayList<>();
|
||||
for (Property property : properties.getProperty()) {
|
||||
if (property.getName().equals(STAT_PERMISSION)) {
|
||||
permission.add(property.getValue());
|
||||
}
|
||||
}
|
||||
return permission;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* 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.carbon.device.mgt.output.adapter.websocket.authorization.client;
|
||||
|
||||
import feign.Feign;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
import feign.auth.BasicAuthRequestInterceptor;
|
||||
import feign.gson.GsonDecoder;
|
||||
import feign.gson.GsonEncoder;
|
||||
import feign.jaxrs.JAXRSContract;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto.AccessTokenInfo;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto.ApiApplicationKey;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto.ApiApplicationRegistrationService;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto.ApiRegistrationProfile;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto.TokenIssuerService;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.config.Properties;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.config.Property;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.config.WebsocketConfig;
|
||||
|
||||
/**
|
||||
* This is a request interceptor to add oauth token header.
|
||||
*/
|
||||
public class OAuthRequestInterceptor implements RequestInterceptor {
|
||||
|
||||
private AccessTokenInfo tokenInfo;
|
||||
private long refreshTimeOffset;
|
||||
private static final String API_APPLICATION_REGISTRATION_CONTEXT = "/api-application-registration";
|
||||
private static final String DEVICE_MANAGEMENT_SERVICE_TAG[] = {"device_management"};
|
||||
private static final String APPLICATION_NAME = "mqtt_broker";
|
||||
private static final String PASSWORD_GRANT_TYPE = "password";
|
||||
private static final String REFRESH_GRANT_TYPE = "refresh_token";
|
||||
private ApiApplicationRegistrationService apiApplicationRegistrationService;
|
||||
private TokenIssuerService tokenIssuerService;
|
||||
|
||||
private static Log logger = LogFactory.getLog(OAuthRequestInterceptor.class);
|
||||
|
||||
private static final String CONNECTION_USERNAME = "username";
|
||||
private static final String CONNECTION_PASSWORD = "password";
|
||||
private static final String TOKEN_ENDPOINT = "tokenEndpoint";
|
||||
private static final String TOKEN_REFRESH_TIME_OFFSET = "tokenRefreshTimeOffset";
|
||||
private static final String DEVICE_MGT_SERVER_URL = "deviceMgtServerUrl";
|
||||
private static String username;
|
||||
private static String password;
|
||||
private static String tokenEndpoint;
|
||||
private static String deviceMgtServerUrl;
|
||||
|
||||
/**
|
||||
* Creates an interceptor that authenticates all requests.
|
||||
*/
|
||||
public OAuthRequestInterceptor() {
|
||||
Properties properties =
|
||||
WebsocketConfig.getInstance().getWebsocketValidationConfigs().getAuthorizer().getProperties();
|
||||
deviceMgtServerUrl = getDeviceMgtServerUrl(properties);
|
||||
refreshTimeOffset = getRefreshTimeOffset(properties);
|
||||
username = getUsername(properties);
|
||||
password = getPassword(properties);
|
||||
tokenEndpoint = getTokenEndpoint(properties);
|
||||
apiApplicationRegistrationService = Feign.builder().requestInterceptor(
|
||||
new BasicAuthRequestInterceptor(username, password))
|
||||
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
|
||||
.target(ApiApplicationRegistrationService.class,
|
||||
deviceMgtServerUrl + API_APPLICATION_REGISTRATION_CONTEXT);
|
||||
}
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
if (tokenInfo == null) {
|
||||
//had to do on demand initialization due to start up error.
|
||||
ApiRegistrationProfile apiRegistrationProfile = new ApiRegistrationProfile();
|
||||
apiRegistrationProfile.setApplicationName(APPLICATION_NAME);
|
||||
apiRegistrationProfile.setIsAllowedToAllDomains(false);
|
||||
apiRegistrationProfile.setIsMappingAnExistingOAuthApp(false);
|
||||
apiRegistrationProfile.setTags(DEVICE_MANAGEMENT_SERVICE_TAG);
|
||||
ApiApplicationKey apiApplicationKey = apiApplicationRegistrationService.register(apiRegistrationProfile);
|
||||
String consumerKey = apiApplicationKey.getConsumerKey();
|
||||
String consumerSecret = apiApplicationKey.getConsumerSecret();
|
||||
tokenIssuerService = Feign.builder().requestInterceptor(
|
||||
new BasicAuthRequestInterceptor(consumerKey, consumerSecret))
|
||||
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
|
||||
.target(TokenIssuerService.class, tokenEndpoint);
|
||||
tokenInfo = tokenIssuerService.getToken(PASSWORD_GRANT_TYPE, username, password);
|
||||
}
|
||||
if (System.currentTimeMillis() + refreshTimeOffset > tokenInfo.getExpires_in()) {
|
||||
tokenInfo = tokenIssuerService.getToken(REFRESH_GRANT_TYPE, tokenInfo.getRefresh_token());
|
||||
}
|
||||
String headerValue = "Bearer " + tokenInfo.getAccess_token();
|
||||
template.header("Authorization", headerValue);
|
||||
}
|
||||
|
||||
private String getUsername(Properties properties) {
|
||||
String username = null;
|
||||
for (Property property : properties.getProperty()) {
|
||||
if (property.getName().equals(CONNECTION_USERNAME)) {
|
||||
username = property.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (username == null || username.isEmpty()) {
|
||||
logger.error("username can't be empty ");
|
||||
}
|
||||
return username;
|
||||
}
|
||||
|
||||
private String getPassword(Properties properties) {
|
||||
String password = null;
|
||||
for (Property property : properties.getProperty()) {
|
||||
if (property.getName().equals(CONNECTION_PASSWORD)) {
|
||||
password = property.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (password == null || password.isEmpty()) {
|
||||
logger.error("password can't be empty ");
|
||||
}
|
||||
return password;
|
||||
}
|
||||
|
||||
private String getDeviceMgtServerUrl(Properties properties) {
|
||||
String deviceMgtServerUrl = null;
|
||||
for (Property property : properties.getProperty()) {
|
||||
if (property.getName().equals(DEVICE_MGT_SERVER_URL)) {
|
||||
deviceMgtServerUrl = property.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (deviceMgtServerUrl == null || deviceMgtServerUrl.isEmpty()) {
|
||||
logger.error("deviceMgtServerUrl can't be empty ");
|
||||
}
|
||||
return deviceMgtServerUrl;
|
||||
}
|
||||
|
||||
private String getTokenEndpoint(Properties properties) {
|
||||
String tokenEndpoint = null;
|
||||
for (Property property : properties.getProperty()) {
|
||||
if (property.getName().equals(TOKEN_ENDPOINT)) {
|
||||
tokenEndpoint = property.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tokenEndpoint == null || tokenEndpoint.isEmpty()) {
|
||||
logger.error("tokenEndpoint can't be empty ");
|
||||
}
|
||||
return tokenEndpoint;
|
||||
}
|
||||
|
||||
private long getRefreshTimeOffset(Properties properties) {
|
||||
long refreshTimeOffset = 0;
|
||||
try {
|
||||
for (Property property : properties.getProperty()) {
|
||||
if (property.getName().equals(TOKEN_REFRESH_TIME_OFFSET)) {
|
||||
refreshTimeOffset = Long.parseLong(property.getValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
logger.error("refreshTimeOffset should be a number", e);
|
||||
}
|
||||
return refreshTimeOffset;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* 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.carbon.device.mgt.output.adapter.websocket.authorization.client.dto;
|
||||
|
||||
/**
|
||||
* This hold access token info that returned from the api call
|
||||
*/
|
||||
public class AccessTokenInfo {
|
||||
public String token_type;
|
||||
public long expires_in;
|
||||
public String refresh_token;
|
||||
public String access_token;
|
||||
|
||||
public String getToken_type() {
|
||||
return token_type;
|
||||
}
|
||||
|
||||
public void setToken_type(String token_type) {
|
||||
this.token_type = token_type;
|
||||
}
|
||||
|
||||
public long getExpires_in() {
|
||||
return expires_in;
|
||||
}
|
||||
|
||||
public void setExpires_in(long expires_in) {
|
||||
this.expires_in = expires_in;
|
||||
}
|
||||
|
||||
public String getRefresh_token() {
|
||||
return refresh_token;
|
||||
}
|
||||
|
||||
public void setRefresh_token(String refresh_token) {
|
||||
this.refresh_token = refresh_token;
|
||||
}
|
||||
|
||||
public String getAccess_token() {
|
||||
return access_token;
|
||||
}
|
||||
|
||||
public void setAccess_token(String access_token) {
|
||||
this.access_token = access_token;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto;
|
||||
|
||||
/**
|
||||
* This holds api application consumer key and secret.
|
||||
*/
|
||||
public class ApiApplicationKey {
|
||||
private String client_id;
|
||||
private String client_secret;
|
||||
|
||||
public String getConsumerKey() {
|
||||
return this.client_id;
|
||||
}
|
||||
|
||||
public void setClient_id(String consumerKey) {
|
||||
this.client_id = consumerKey;
|
||||
}
|
||||
|
||||
public String getConsumerSecret() {
|
||||
return this.client_secret;
|
||||
}
|
||||
|
||||
public void setClient_secret(String consumerSecret) {
|
||||
this.client_secret = consumerSecret;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
/**
|
||||
* This is the application registration service that exposed for apimApplicationRegistration
|
||||
*/
|
||||
|
||||
@Path("/register")
|
||||
public interface ApiApplicationRegistrationService {
|
||||
|
||||
/**
|
||||
* This method is used to register api application
|
||||
*
|
||||
* @param registrationProfile contains the necessary attributes that are needed in order to register an app.
|
||||
*/
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
ApiApplicationKey register(ApiRegistrationProfile registrationProfile);
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* 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.carbon.device.mgt.output.adapter.websocket.authorization.client.dto;
|
||||
|
||||
|
||||
/**
|
||||
* This class represents the data that are required to register
|
||||
* the oauth application.
|
||||
*/
|
||||
public class ApiRegistrationProfile {
|
||||
|
||||
public String applicationName;
|
||||
public String tags[];
|
||||
public boolean isAllowedToAllDomains;
|
||||
public String consumerKey;
|
||||
public String consumerSecret;
|
||||
public boolean isMappingAnExistingOAuthApp;
|
||||
|
||||
public String getApplicationName() {
|
||||
return applicationName;
|
||||
}
|
||||
|
||||
public void setApplicationName(String applicationName) {
|
||||
this.applicationName = applicationName;
|
||||
}
|
||||
|
||||
public String[] getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setTags(String[] tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public boolean isAllowedToAllDomains() {
|
||||
return isAllowedToAllDomains;
|
||||
}
|
||||
|
||||
public void setIsAllowedToAllDomains(boolean isAllowedToAllDomains) {
|
||||
this.isAllowedToAllDomains = isAllowedToAllDomains;
|
||||
}
|
||||
|
||||
public boolean isMappingAnExistingOAuthApp() {
|
||||
return isMappingAnExistingOAuthApp;
|
||||
}
|
||||
|
||||
public void setIsMappingAnExistingOAuthApp(boolean isMappingAnExistingOAuthApp) {
|
||||
this.isMappingAnExistingOAuthApp = isMappingAnExistingOAuthApp;
|
||||
}
|
||||
|
||||
public String getConsumerKey() {
|
||||
return consumerKey;
|
||||
}
|
||||
|
||||
public void setConsumerKey(String consumerKey) {
|
||||
this.consumerKey = consumerKey;
|
||||
}
|
||||
|
||||
public String getConsumerSecret() {
|
||||
return consumerSecret;
|
||||
}
|
||||
|
||||
public void setConsumerSecret(String consumerSecret) {
|
||||
this.consumerSecret = consumerSecret;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* DTO of the authorization request
|
||||
*/
|
||||
public class AuthorizationRequest {
|
||||
|
||||
String tenantDomain;
|
||||
String username;
|
||||
List<DeviceIdentifier> deviceIdentifiers;
|
||||
List<String> permissions;
|
||||
|
||||
public String getTenantDomain() {
|
||||
return tenantDomain;
|
||||
}
|
||||
|
||||
public void setTenantDomain(String tenantDomain) {
|
||||
this.tenantDomain = tenantDomain;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public List<DeviceIdentifier> getDeviceIdentifiers() {
|
||||
return deviceIdentifiers;
|
||||
}
|
||||
|
||||
public void setDeviceIdentifiers(List<DeviceIdentifier> deviceIdentifiers) {
|
||||
this.deviceIdentifiers = deviceIdentifiers;
|
||||
}
|
||||
|
||||
public List<String> getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public void setPermissions(List<String> permissions) {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto;
|
||||
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/admin/authorization")
|
||||
/**
|
||||
* This interface provided the definition of the device - user access verification service.
|
||||
*/
|
||||
public interface DeviceAccessAuthorizationAdminService {
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
DeviceAuthorizationResult isAuthorized(AuthorizationRequest authorizationRequest);
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a DeviceAuthorizationResult including a list of authorized devices and a list of unauthorized devices.
|
||||
*/
|
||||
public class DeviceAuthorizationResult {
|
||||
|
||||
private List<DeviceIdentifier> authorizedDevices = new ArrayList<>();
|
||||
private List<DeviceIdentifier> unauthorizedDevices = new ArrayList<>();
|
||||
|
||||
public List<DeviceIdentifier> getAuthorizedDevices() {
|
||||
return authorizedDevices;
|
||||
}
|
||||
|
||||
public void setAuthorizedDevices(List<DeviceIdentifier> authorizedDevices) {
|
||||
this.authorizedDevices = authorizedDevices;
|
||||
}
|
||||
|
||||
public void setUnauthorizedDevices(
|
||||
List<DeviceIdentifier> unauthorizedDevices) {
|
||||
this.unauthorizedDevices = unauthorizedDevices;
|
||||
}
|
||||
|
||||
public void addAuthorizedDevice(DeviceIdentifier deviceIdentifier) {
|
||||
authorizedDevices.add(deviceIdentifier);
|
||||
}
|
||||
|
||||
public List<DeviceIdentifier> getUnauthorizedDevices() {
|
||||
return unauthorizedDevices;
|
||||
}
|
||||
|
||||
public void addUnauthorizedDevice(DeviceIdentifier deviceIdentifier) {
|
||||
unauthorizedDevices.add(deviceIdentifier);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* DTO of the device identifier
|
||||
*/
|
||||
public class DeviceIdentifier implements Serializable{
|
||||
|
||||
private String id;
|
||||
private String type;
|
||||
|
||||
public DeviceIdentifier() {}
|
||||
|
||||
public DeviceIdentifier(String id, String type) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type.toLowerCase();
|
||||
}
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* 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.carbon.device.mgt.output.adapter.websocket.authorization.client.dto;
|
||||
|
||||
/**
|
||||
* This class represents an OAuth application populated with necessary data.
|
||||
*/
|
||||
public class OAuthApplicationInfo {
|
||||
|
||||
public String client_id;
|
||||
public String client_name;
|
||||
public String callback_url;
|
||||
public String client_secret;
|
||||
|
||||
public String getClient_id() {
|
||||
return client_id;
|
||||
}
|
||||
|
||||
public void setClient_id(String client_id) {
|
||||
this.client_id = client_id;
|
||||
}
|
||||
|
||||
public String getClient_name() {
|
||||
return client_name;
|
||||
}
|
||||
|
||||
public void setClient_name(String client_name) {
|
||||
this.client_name = client_name;
|
||||
}
|
||||
|
||||
public String getCallback_url() {
|
||||
return callback_url;
|
||||
}
|
||||
|
||||
public void setCallback_url(String callback_url) {
|
||||
this.callback_url = callback_url;
|
||||
}
|
||||
|
||||
public String getClient_secret() {
|
||||
return client_secret;
|
||||
}
|
||||
|
||||
public void setClient_secret(String client_secret) {
|
||||
this.client_secret = client_secret;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* 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.carbon.device.mgt.output.adapter.websocket.authorization.client.dto;
|
||||
|
||||
/**
|
||||
* This holds the data related to registration.
|
||||
*/
|
||||
public class RegisterInfo {
|
||||
|
||||
private boolean isRegistered;
|
||||
private String msg;
|
||||
|
||||
public boolean isRegistered() {
|
||||
return isRegistered;
|
||||
}
|
||||
|
||||
public void setIsRegistered(boolean isRegistered) {
|
||||
this.isRegistered = isRegistered;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
package org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.dto;
|
||||
|
||||
|
||||
/**
|
||||
* This class represents the data that are required to register
|
||||
* the oauth application.
|
||||
*/
|
||||
public class RegistrationProfile {
|
||||
|
||||
public String callbackUrl;
|
||||
public String clientName;
|
||||
public String tokenScope;
|
||||
public String owner;
|
||||
public String grantType;
|
||||
public String applicationType;
|
||||
|
||||
public String getCallbackUrl() {
|
||||
return callbackUrl;
|
||||
}
|
||||
|
||||
public void setCallbackUrl(String callBackUrl) {
|
||||
this.callbackUrl = callBackUrl;
|
||||
}
|
||||
|
||||
public String getClientName() {
|
||||
return clientName;
|
||||
}
|
||||
|
||||
public void setClientName(String clientName) {
|
||||
this.clientName = clientName;
|
||||
}
|
||||
|
||||
public String getTokenScope() {
|
||||
return tokenScope;
|
||||
}
|
||||
|
||||
public void setTokenScope(String tokenScope) {
|
||||
this.tokenScope = tokenScope;
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public void setOwner(String owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public String getGrantType() {
|
||||
return grantType;
|
||||
}
|
||||
|
||||
public void setGrantType(String grantType) {
|
||||
this.grantType = grantType;
|
||||
}
|
||||
|
||||
public String getApplicationType() {
|
||||
return applicationType;
|
||||
}
|
||||
|
||||
public void setApplicationType(String applicationType) {
|
||||
this.applicationType = applicationType;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* 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.carbon.device.mgt.output.adapter.websocket.authorization.client.dto;
|
||||
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
/**
|
||||
* This hold the api defintion that is used as a contract with netflix feign.
|
||||
*/
|
||||
@Path("/token")
|
||||
public interface TokenIssuerService {
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
AccessTokenInfo getToken(@QueryParam("grant_type") String grant, @QueryParam("username") String username,
|
||||
@QueryParam("password") String password);
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
AccessTokenInfo getToken(@QueryParam("grant_type") String grant, @QueryParam("refresh_token") String refreshToken);
|
||||
}
|
||||
@ -18,6 +18,8 @@
|
||||
|
||||
package org.wso2.carbon.device.mgt.output.adapter.websocket.config;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.wso2.carbon.device.mgt.output.adapter.websocket.util.WebsocketUtils;
|
||||
import org.wso2.carbon.utils.CarbonUtils;
|
||||
@ -34,6 +36,7 @@ public class WebsocketConfig {
|
||||
|
||||
private static WebsocketConfig config = new WebsocketConfig();
|
||||
private WebsocketValidationConfigs websocketValidationConfigs;
|
||||
private static final Log log = LogFactory.getLog(WebsocketConfig.class);
|
||||
|
||||
private static final String WEBSOCKET_VALIDATION_CONFIG_PATH =
|
||||
CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + "websocket-validation.xml";
|
||||
@ -62,6 +65,13 @@ public class WebsocketConfig {
|
||||
}
|
||||
|
||||
public WebsocketValidationConfigs getWebsocketValidationConfigs() {
|
||||
if (websocketValidationConfigs == null) {
|
||||
try {
|
||||
init();
|
||||
} catch (WebsocketValidationConfigurationFailedException e) {
|
||||
log.error("failed to initialize the config", e);
|
||||
}
|
||||
}
|
||||
return websocketValidationConfigs;
|
||||
}
|
||||
|
||||
|
||||
@ -58,6 +58,26 @@
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-jaxrs</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-gson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>jsr311-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>javax.cache.wso2</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@ -95,9 +115,20 @@
|
||||
org.wso2.carbon.user.core.service,
|
||||
org.wso2.carbon.user.core.tenant,
|
||||
org.wso2.carbon.user.api,
|
||||
*;resolution:=optional
|
||||
feign,
|
||||
feign.auth,
|
||||
feign.codec,
|
||||
feign.gson,
|
||||
javax.cache,
|
||||
javax.xml.namespace,
|
||||
javax.xml.stream,
|
||||
org.wso2.carbon.base,
|
||||
org.wso2.carbon.utils
|
||||
</Import-Package>
|
||||
<DynamicImport-Package>*</DynamicImport-Package>
|
||||
<Embed-Dependency>
|
||||
jsr311-api,
|
||||
feign-jaxrs
|
||||
</Embed-Dependency>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
@ -18,18 +18,36 @@
|
||||
|
||||
package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization;
|
||||
|
||||
import feign.Feign;
|
||||
import feign.FeignException;
|
||||
import feign.gson.GsonDecoder;
|
||||
import feign.gson.GsonEncoder;
|
||||
import feign.jaxrs.JAXRSContract;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.dna.mqtt.moquette.server.IAuthorizer;
|
||||
import org.wso2.andes.configuration.enums.MQTTAuthoriztionPermissionLevel;
|
||||
import org.wso2.andes.mqtt.MQTTAuthorizationSubject;
|
||||
import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.OAuthRequestInterceptor;
|
||||
import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto.AuthorizationRequest;
|
||||
import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto.DeviceAccessAuthorizationAdminService;
|
||||
import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto.DeviceAuthorizationResult;
|
||||
import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto.DeviceIdentifier;
|
||||
import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.config.AuthorizationConfigurationManager;
|
||||
import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.internal.AuthorizationDataHolder;
|
||||
import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.util.AuthorizationCacheKey;
|
||||
import org.wso2.carbon.base.MultitenantConstants;
|
||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
import org.wso2.carbon.user.api.UserRealm;
|
||||
import org.wso2.carbon.user.api.UserStoreException;
|
||||
|
||||
import javax.cache.Cache;
|
||||
import javax.cache.CacheConfiguration;
|
||||
import javax.cache.CacheManager;
|
||||
import javax.cache.Caching;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Authorize the connecting users against Carbon Permission Model. Intended usage is
|
||||
@ -39,13 +57,24 @@ import java.util.List;
|
||||
*/
|
||||
public class DeviceAccessBasedMQTTAuthorizer implements IAuthorizer {
|
||||
|
||||
private static final String SCOPE_IDENTIFIER = "scope";
|
||||
private static final String UI_EXECUTE = "ui.execute";
|
||||
private static Log logger = LogFactory.getLog(DeviceAccessBasedMQTTAuthorizer.class);
|
||||
AuthorizationConfigurationManager MQTTAuthorizationConfiguration;
|
||||
private static final String CDMF_SERVER_BASE_CONTEXT = "/api/device-mgt/v1.0";
|
||||
private static final String CACHE_MANAGER_NAME = "mqttAuthorizationCacheManager";
|
||||
private static final String CACHE_NAME = "mqttAuthorizationCache";
|
||||
private static DeviceAccessAuthorizationAdminService deviceAccessAuthorizationAdminService;
|
||||
private static Cache<AuthorizationCacheKey, Boolean> cache;
|
||||
|
||||
|
||||
public DeviceAccessBasedMQTTAuthorizer() {
|
||||
this.MQTTAuthorizationConfiguration = AuthorizationConfigurationManager.getInstance();
|
||||
createCache();
|
||||
deviceAccessAuthorizationAdminService = Feign.builder()
|
||||
.requestInterceptor(new OAuthRequestInterceptor())
|
||||
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
|
||||
.target(DeviceAccessAuthorizationAdminService.class,
|
||||
MQTTAuthorizationConfiguration.getDeviceMgtServerUrl() + CDMF_SERVER_BASE_CONTEXT);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -54,35 +83,73 @@ public class DeviceAccessBasedMQTTAuthorizer implements IAuthorizer {
|
||||
@Override
|
||||
public boolean isAuthorizedForTopic(MQTTAuthorizationSubject authorizationSubject, String topic,
|
||||
MQTTAuthoriztionPermissionLevel permissionLevel) {
|
||||
if (isUserAuthorized(authorizationSubject, MQTTAuthorizationConfiguration.getAdminPermission(), UI_EXECUTE)) {
|
||||
String topics[] = topic.split("/");
|
||||
String tenantDomainFromTopic = topics[0];
|
||||
if (!tenantDomainFromTopic.equals(authorizationSubject.getTenantDomain())) {
|
||||
return false;
|
||||
}
|
||||
if (topics.length < 3) {
|
||||
AuthorizationCacheKey authorizationCacheKey = new AuthorizationCacheKey(tenantDomainFromTopic
|
||||
,authorizationSubject.getUsername(), "", "");
|
||||
if (cache.get(authorizationCacheKey)) {
|
||||
return true;
|
||||
}
|
||||
String topics[] = topic.split("/");
|
||||
if (topics.length < 3) {
|
||||
AuthorizationRequest authorizationRequest = new AuthorizationRequest();
|
||||
authorizationRequest.setTenantDomain(tenantDomainFromTopic);
|
||||
try {
|
||||
DeviceAuthorizationResult deviceAuthorizationResult =
|
||||
deviceAccessAuthorizationAdminService.isAuthorized(authorizationRequest);
|
||||
if (deviceAuthorizationResult != null) {
|
||||
cache.put(authorizationCacheKey, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (FeignException e) {
|
||||
return false;
|
||||
}
|
||||
String tenantIdFromTopic = topics[0];
|
||||
if (!tenantIdFromTopic.equals(authorizationSubject.getTenantDomain())) {
|
||||
return false;
|
||||
}
|
||||
String deviceType = topics[1];
|
||||
String deviceId = topics[2];
|
||||
Object scopeObject = authorizationSubject.getProperties().get(SCOPE_IDENTIFIER);
|
||||
|
||||
if (!deviceId.isEmpty() && !deviceType.isEmpty() && scopeObject != null) {
|
||||
List<String> scopes = (List<String>) scopeObject;
|
||||
String permissionScope = MQTTAuthorizationConfiguration.getMQTTPublisherScopeIdentifier();
|
||||
if (permissionLevel == MQTTAuthoriztionPermissionLevel.SUBSCRIBE) {
|
||||
permissionScope = MQTTAuthorizationConfiguration.getMQTTSubscriberScopeIdentifier();
|
||||
AuthorizationCacheKey authorizationCacheKey = new AuthorizationCacheKey(tenantDomainFromTopic
|
||||
,authorizationSubject.getUsername(), deviceId, deviceType);
|
||||
if (cache.get(authorizationCacheKey)) {
|
||||
return true;
|
||||
}
|
||||
String requiredScope = MQTTAuthorizationConfiguration.getDevicemgtScopeIdentifier() + ":" + deviceType + ":"
|
||||
+ deviceId + ":" + permissionScope;
|
||||
for (String scope : scopes) {
|
||||
if (requiredScope.equals(scope)) {
|
||||
|
||||
List<String> requiredPermission;
|
||||
if (permissionLevel == MQTTAuthoriztionPermissionLevel.SUBSCRIBE) {
|
||||
requiredPermission = MQTTAuthorizationConfiguration.getSubscriberPermissions();
|
||||
} else {
|
||||
requiredPermission = MQTTAuthorizationConfiguration.getPublisherPermissions();
|
||||
}
|
||||
|
||||
AuthorizationRequest authorizationRequest = new AuthorizationRequest();
|
||||
authorizationRequest.setTenantDomain(tenantDomainFromTopic);
|
||||
if (requiredPermission != null) {
|
||||
authorizationRequest.setPermissions(requiredPermission);
|
||||
}
|
||||
authorizationRequest.setUsername(authorizationSubject.getUsername());
|
||||
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
|
||||
deviceIdentifier.setId(deviceId);
|
||||
deviceIdentifier.setType(deviceType);
|
||||
List<DeviceIdentifier> deviceIdentifiers = new ArrayList<>();
|
||||
deviceIdentifiers.add(deviceIdentifier);
|
||||
authorizationRequest.setDeviceIdentifiers(deviceIdentifiers);
|
||||
try {
|
||||
DeviceAuthorizationResult deviceAuthorizationResult =
|
||||
deviceAccessAuthorizationAdminService.isAuthorized(authorizationRequest);
|
||||
List<DeviceIdentifier> devices = deviceAuthorizationResult.getAuthorizedDevices();
|
||||
if (devices != null && devices.size() > 0) {
|
||||
DeviceIdentifier authorizedDevice = devices.get(0);
|
||||
if (authorizedDevice.getId().equals(deviceId) && authorizedDevice.getType().equals(deviceType)) {
|
||||
cache.put(authorizationCacheKey, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (FeignException e) {
|
||||
// do nothing.
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -91,6 +158,11 @@ public class DeviceAccessBasedMQTTAuthorizer implements IAuthorizer {
|
||||
*/
|
||||
@Override
|
||||
public boolean isAuthorizedToConnect(MQTTAuthorizationSubject authorizationSubject) {
|
||||
if (MQTTAuthorizationConfiguration.getConnectionPermission() == null ||
|
||||
MQTTAuthorizationConfiguration.getConnectionPermission().isEmpty()) {
|
||||
//allow authenticated client to connect.
|
||||
return true;
|
||||
}
|
||||
return isUserAuthorized(authorizationSubject, MQTTAuthorizationConfiguration.getConnectionPermission()
|
||||
, UI_EXECUTE);
|
||||
}
|
||||
@ -122,4 +194,28 @@ public class DeviceAccessBasedMQTTAuthorizer implements IAuthorizer {
|
||||
PrivilegedCarbonContext.endTenantFlow();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to create the Caches.
|
||||
* @return Cachemanager
|
||||
*/
|
||||
private void createCache() {
|
||||
PrivilegedCarbonContext.startTenantFlow();
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
|
||||
MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true);
|
||||
try {
|
||||
CacheManager cacheManager = Caching.getCacheManagerFactory().getCacheManager(CACHE_MANAGER_NAME);
|
||||
if (MQTTAuthorizationConfiguration.getCacheDuration() == 0) {
|
||||
cache = cacheManager.getCache(CACHE_NAME);
|
||||
} else {
|
||||
cache = cacheManager.<AuthorizationCacheKey, Boolean>createCacheBuilder(CACHE_NAME).
|
||||
setExpiry(CacheConfiguration.ExpiryType.MODIFIED, new CacheConfiguration.Duration(
|
||||
TimeUnit.SECONDS, MQTTAuthorizationConfiguration.getCacheDuration())).
|
||||
setStoreByValue(false).build();
|
||||
}
|
||||
} finally {
|
||||
PrivilegedCarbonContext.endTenantFlow();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* 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.carbon.andes.extensions.device.mgt.mqtt.authorization.client;
|
||||
|
||||
import feign.Feign;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
import feign.auth.BasicAuthRequestInterceptor;
|
||||
import feign.gson.GsonDecoder;
|
||||
import feign.gson.GsonEncoder;
|
||||
import feign.jaxrs.JAXRSContract;
|
||||
import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto.AccessTokenInfo;
|
||||
import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto.ApiApplicationKey;
|
||||
import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto.ApiApplicationRegistrationService;
|
||||
import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto.ApiRegistrationProfile;
|
||||
import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto.TokenIssuerService;
|
||||
import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.config.AuthorizationConfigurationManager;
|
||||
|
||||
/**
|
||||
* This is a request interceptor to add oauth token header.
|
||||
*/
|
||||
public class OAuthRequestInterceptor implements RequestInterceptor {
|
||||
|
||||
private AccessTokenInfo tokenInfo;
|
||||
private long refreshTimeOffset;
|
||||
private static final String API_APPLICATION_REGISTRATION_CONTEXT = "/api-application-registration";
|
||||
private static final String DEVICE_MANAGEMENT_SERVICE_TAG[] = {"device_management"};
|
||||
private static final String APPLICATION_NAME = "mqtt_broker";
|
||||
private static final String PASSWORD_GRANT_TYPE = "password";
|
||||
private static final String REFRESH_GRANT_TYPE = "refresh_token";
|
||||
private ApiApplicationRegistrationService apiApplicationRegistrationService;
|
||||
private TokenIssuerService tokenIssuerService;
|
||||
|
||||
/**
|
||||
* Creates an interceptor that authenticates all requests.
|
||||
*/
|
||||
public OAuthRequestInterceptor() {
|
||||
refreshTimeOffset = AuthorizationConfigurationManager.getInstance().getTokenRefreshTimeOffset();
|
||||
String username = AuthorizationConfigurationManager.getInstance().getUsername();
|
||||
String password = AuthorizationConfigurationManager.getInstance().getPassword();
|
||||
apiApplicationRegistrationService = Feign.builder().requestInterceptor(
|
||||
new BasicAuthRequestInterceptor(username, password))
|
||||
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
|
||||
.target(ApiApplicationRegistrationService.class,
|
||||
AuthorizationConfigurationManager.getInstance().getDeviceMgtServerUrl() +
|
||||
API_APPLICATION_REGISTRATION_CONTEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
if (tokenInfo == null) {
|
||||
//had to do on demand initialization due to start up error.
|
||||
ApiRegistrationProfile apiRegistrationProfile = new ApiRegistrationProfile();
|
||||
apiRegistrationProfile.setApplicationName(APPLICATION_NAME);
|
||||
apiRegistrationProfile.setIsAllowedToAllDomains(false);
|
||||
apiRegistrationProfile.setIsMappingAnExistingOAuthApp(false);
|
||||
apiRegistrationProfile.setTags(DEVICE_MANAGEMENT_SERVICE_TAG);
|
||||
ApiApplicationKey apiApplicationKey = apiApplicationRegistrationService.register(apiRegistrationProfile);
|
||||
String consumerKey = apiApplicationKey.getConsumerKey();
|
||||
String consumerSecret = apiApplicationKey.getConsumerSecret();
|
||||
String username = AuthorizationConfigurationManager.getInstance().getUsername();
|
||||
String password = AuthorizationConfigurationManager.getInstance().getPassword();
|
||||
tokenIssuerService = Feign.builder().requestInterceptor(
|
||||
new BasicAuthRequestInterceptor(consumerKey, consumerSecret))
|
||||
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
|
||||
.target(TokenIssuerService.class, AuthorizationConfigurationManager.getInstance().getTokenEndpoint());
|
||||
tokenInfo = tokenIssuerService.getToken(PASSWORD_GRANT_TYPE, username, password);
|
||||
}
|
||||
if (System.currentTimeMillis() + refreshTimeOffset > tokenInfo.getExpires_in()) {
|
||||
tokenInfo = tokenIssuerService.getToken(REFRESH_GRANT_TYPE, tokenInfo.getRefresh_token());
|
||||
}
|
||||
String headerValue = "Bearer " + tokenInfo.getAccess_token();
|
||||
template.header("Authorization", headerValue);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* 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.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto;
|
||||
|
||||
/**
|
||||
* This hold access token info that returned from the api call
|
||||
*/
|
||||
public class AccessTokenInfo {
|
||||
public String token_type;
|
||||
public long expires_in;
|
||||
public String refresh_token;
|
||||
public String access_token;
|
||||
|
||||
public String getToken_type() {
|
||||
return token_type;
|
||||
}
|
||||
|
||||
public void setToken_type(String token_type) {
|
||||
this.token_type = token_type;
|
||||
}
|
||||
|
||||
public long getExpires_in() {
|
||||
return expires_in;
|
||||
}
|
||||
|
||||
public void setExpires_in(long expires_in) {
|
||||
this.expires_in = expires_in;
|
||||
}
|
||||
|
||||
public String getRefresh_token() {
|
||||
return refresh_token;
|
||||
}
|
||||
|
||||
public void setRefresh_token(String refresh_token) {
|
||||
this.refresh_token = refresh_token;
|
||||
}
|
||||
|
||||
public String getAccess_token() {
|
||||
return access_token;
|
||||
}
|
||||
|
||||
public void setAccess_token(String access_token) {
|
||||
this.access_token = access_token;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto;
|
||||
|
||||
/**
|
||||
* This holds api application consumer key and secret.
|
||||
*/
|
||||
public class ApiApplicationKey {
|
||||
private String client_id;
|
||||
private String client_secret;
|
||||
|
||||
public String getConsumerKey() {
|
||||
return this.client_id;
|
||||
}
|
||||
|
||||
public void setClient_id(String consumerKey) {
|
||||
this.client_id = consumerKey;
|
||||
}
|
||||
|
||||
public String getConsumerSecret() {
|
||||
return this.client_secret;
|
||||
}
|
||||
|
||||
public void setClient_secret(String consumerSecret) {
|
||||
this.client_secret = consumerSecret;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
/**
|
||||
* This is the application registration service that exposed for apimApplicationRegistration
|
||||
*/
|
||||
|
||||
@Path("/register")
|
||||
public interface ApiApplicationRegistrationService {
|
||||
|
||||
/**
|
||||
* This method is used to register api application
|
||||
*
|
||||
* @param registrationProfile contains the necessary attributes that are needed in order to register an app.
|
||||
*/
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
ApiApplicationKey register(ApiRegistrationProfile registrationProfile);
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* 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.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto;
|
||||
|
||||
|
||||
/**
|
||||
* This class represents the data that are required to register
|
||||
* the oauth application.
|
||||
*/
|
||||
public class ApiRegistrationProfile {
|
||||
|
||||
public String applicationName;
|
||||
public String tags[];
|
||||
public boolean isAllowedToAllDomains;
|
||||
public String consumerKey;
|
||||
public String consumerSecret;
|
||||
public boolean isMappingAnExistingOAuthApp;
|
||||
|
||||
public String getApplicationName() {
|
||||
return applicationName;
|
||||
}
|
||||
|
||||
public void setApplicationName(String applicationName) {
|
||||
this.applicationName = applicationName;
|
||||
}
|
||||
|
||||
public String[] getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setTags(String[] tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public boolean isAllowedToAllDomains() {
|
||||
return isAllowedToAllDomains;
|
||||
}
|
||||
|
||||
public void setIsAllowedToAllDomains(boolean isAllowedToAllDomains) {
|
||||
this.isAllowedToAllDomains = isAllowedToAllDomains;
|
||||
}
|
||||
|
||||
public boolean isMappingAnExistingOAuthApp() {
|
||||
return isMappingAnExistingOAuthApp;
|
||||
}
|
||||
|
||||
public void setIsMappingAnExistingOAuthApp(boolean isMappingAnExistingOAuthApp) {
|
||||
this.isMappingAnExistingOAuthApp = isMappingAnExistingOAuthApp;
|
||||
}
|
||||
|
||||
public String getConsumerKey() {
|
||||
return consumerKey;
|
||||
}
|
||||
|
||||
public void setConsumerKey(String consumerKey) {
|
||||
this.consumerKey = consumerKey;
|
||||
}
|
||||
|
||||
public String getConsumerSecret() {
|
||||
return consumerSecret;
|
||||
}
|
||||
|
||||
public void setConsumerSecret(String consumerSecret) {
|
||||
this.consumerSecret = consumerSecret;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* DTO of the authorization request
|
||||
*/
|
||||
public class AuthorizationRequest {
|
||||
|
||||
String tenantDomain;
|
||||
String username;
|
||||
List<DeviceIdentifier> deviceIdentifiers;
|
||||
List<String> permissions;
|
||||
|
||||
public String getTenantDomain() {
|
||||
return tenantDomain;
|
||||
}
|
||||
|
||||
public void setTenantDomain(String tenantDomain) {
|
||||
this.tenantDomain = tenantDomain;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public List<DeviceIdentifier> getDeviceIdentifiers() {
|
||||
return deviceIdentifiers;
|
||||
}
|
||||
|
||||
public void setDeviceIdentifiers(List<DeviceIdentifier> deviceIdentifiers) {
|
||||
this.deviceIdentifiers = deviceIdentifiers;
|
||||
}
|
||||
|
||||
public List<String> getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public void setPermissions(List<String> permissions) {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto;
|
||||
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/admin/authorization")
|
||||
/**
|
||||
* This interface provided the definition of the device - user access verification service.
|
||||
*/
|
||||
public interface DeviceAccessAuthorizationAdminService {
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
DeviceAuthorizationResult isAuthorized(AuthorizationRequest authorizationRequest);
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a DeviceAuthorizationResult including a list of authorized devices and a list of unauthorized devices.
|
||||
*/
|
||||
public class DeviceAuthorizationResult {
|
||||
|
||||
private List<DeviceIdentifier> authorizedDevices = new ArrayList<>();
|
||||
private List<DeviceIdentifier> unauthorizedDevices = new ArrayList<>();
|
||||
|
||||
public List<DeviceIdentifier> getAuthorizedDevices() {
|
||||
return authorizedDevices;
|
||||
}
|
||||
|
||||
public void setAuthorizedDevices(List<DeviceIdentifier> authorizedDevices) {
|
||||
this.authorizedDevices = authorizedDevices;
|
||||
}
|
||||
|
||||
public void setUnauthorizedDevices(
|
||||
List<DeviceIdentifier> unauthorizedDevices) {
|
||||
this.unauthorizedDevices = unauthorizedDevices;
|
||||
}
|
||||
|
||||
public void addAuthorizedDevice(DeviceIdentifier deviceIdentifier) {
|
||||
authorizedDevices.add(deviceIdentifier);
|
||||
}
|
||||
|
||||
public List<DeviceIdentifier> getUnauthorizedDevices() {
|
||||
return unauthorizedDevices;
|
||||
}
|
||||
|
||||
public void addUnauthorizedDevice(DeviceIdentifier deviceIdentifier) {
|
||||
unauthorizedDevices.add(deviceIdentifier);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* DTO of the device identifier
|
||||
*/
|
||||
public class DeviceIdentifier implements Serializable{
|
||||
|
||||
private String id;
|
||||
private String type;
|
||||
|
||||
public DeviceIdentifier() {}
|
||||
|
||||
public DeviceIdentifier(String id, String type) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type.toLowerCase();
|
||||
}
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* 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.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto;
|
||||
|
||||
/**
|
||||
* This class represents an OAuth application populated with necessary data.
|
||||
*/
|
||||
public class OAuthApplicationInfo {
|
||||
|
||||
public String client_id;
|
||||
public String client_name;
|
||||
public String callback_url;
|
||||
public String client_secret;
|
||||
|
||||
public String getClient_id() {
|
||||
return client_id;
|
||||
}
|
||||
|
||||
public void setClient_id(String client_id) {
|
||||
this.client_id = client_id;
|
||||
}
|
||||
|
||||
public String getClient_name() {
|
||||
return client_name;
|
||||
}
|
||||
|
||||
public void setClient_name(String client_name) {
|
||||
this.client_name = client_name;
|
||||
}
|
||||
|
||||
public String getCallback_url() {
|
||||
return callback_url;
|
||||
}
|
||||
|
||||
public void setCallback_url(String callback_url) {
|
||||
this.callback_url = callback_url;
|
||||
}
|
||||
|
||||
public String getClient_secret() {
|
||||
return client_secret;
|
||||
}
|
||||
|
||||
public void setClient_secret(String client_secret) {
|
||||
this.client_secret = client_secret;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* 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.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto;
|
||||
|
||||
/**
|
||||
* This holds the data related to registration.
|
||||
*/
|
||||
public class RegisterInfo {
|
||||
|
||||
private boolean isRegistered;
|
||||
private String msg;
|
||||
|
||||
public boolean isRegistered() {
|
||||
return isRegistered;
|
||||
}
|
||||
|
||||
public void setIsRegistered(boolean isRegistered) {
|
||||
this.isRegistered = isRegistered;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto;
|
||||
|
||||
|
||||
/**
|
||||
* This class represents the data that are required to register
|
||||
* the oauth application.
|
||||
*/
|
||||
public class RegistrationProfile {
|
||||
|
||||
public String callbackUrl;
|
||||
public String clientName;
|
||||
public String tokenScope;
|
||||
public String owner;
|
||||
public String grantType;
|
||||
public String applicationType;
|
||||
|
||||
public String getCallbackUrl() {
|
||||
return callbackUrl;
|
||||
}
|
||||
|
||||
public void setCallbackUrl(String callBackUrl) {
|
||||
this.callbackUrl = callBackUrl;
|
||||
}
|
||||
|
||||
public String getClientName() {
|
||||
return clientName;
|
||||
}
|
||||
|
||||
public void setClientName(String clientName) {
|
||||
this.clientName = clientName;
|
||||
}
|
||||
|
||||
public String getTokenScope() {
|
||||
return tokenScope;
|
||||
}
|
||||
|
||||
public void setTokenScope(String tokenScope) {
|
||||
this.tokenScope = tokenScope;
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public void setOwner(String owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public String getGrantType() {
|
||||
return grantType;
|
||||
}
|
||||
|
||||
public void setGrantType(String grantType) {
|
||||
this.grantType = grantType;
|
||||
}
|
||||
|
||||
public String getApplicationType() {
|
||||
return applicationType;
|
||||
}
|
||||
|
||||
public void setApplicationType(String applicationType) {
|
||||
this.applicationType = applicationType;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* 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.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto;
|
||||
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
/**
|
||||
* This hold the api defintion that is used as a contract with netflix feign.
|
||||
*/
|
||||
@Path("/token")
|
||||
public interface TokenIssuerService {
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
AccessTokenInfo getToken(@QueryParam("grant_type") String grant, @QueryParam("username") String username,
|
||||
@QueryParam("password") String password);
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
AccessTokenInfo getToken(@QueryParam("grant_type") String grant, @QueryParam("refresh_token") String refreshToken);
|
||||
}
|
||||
@ -21,23 +21,34 @@ package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.config;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AuthorizationConfigurationManager {
|
||||
|
||||
private static final String CONNECTION_PERMISSION = "connectionPermission";
|
||||
private static final String ADMIN_PERMISSION = "adminPermission";
|
||||
private static final String MQTT_PUBLISHER_SCOPE_IDENTIFIER = "MQTTPublisherScopeIdentifier";
|
||||
private static final String MQTT_SUBSCRIBER_SCOPE_IDENTIFIER = "MQTTSubscriberScopeIdentifier";
|
||||
private static final String DEVICE_MGT_SCOPE_IDENTIFIER = "devicemgtScopeIdentifier";
|
||||
private static final String MQTT_PUBLISHER_PERMISSION = "publisherPermission";
|
||||
private static final String MQTT_SUBSCRIBER_PERMISSION = "subscriberPermission";
|
||||
private static final String CONNECTION_USERNAME = "username";
|
||||
private static final String CONNECTION_PASSWORD = "password";
|
||||
private static final String TOKEN_ENDPOINT = "tokenEndpoint";
|
||||
private static final String TOKEN_REFRESH_TIME_OFFSET = "tokenRefreshTimeOffset";
|
||||
private static final String DEVICE_MGT_SERVER_URL = "deviceMgtServerUrl";
|
||||
private static final String MQTT_CACHE_DURATION = "cacheDurationSeconds";
|
||||
|
||||
private static final AuthorizationConfigurationManager oAuthConfigurationManager
|
||||
= new AuthorizationConfigurationManager();
|
||||
private static Log logger = LogFactory.getLog(AuthorizationConfigurationManager.class);
|
||||
private String connectionPermission;
|
||||
private String adminPermission;
|
||||
private String MQTTPublisherScopeIdentifier;
|
||||
private String MQTTSubscriberScopeIdentifier;
|
||||
private String devicemgtScopeIdentifier;
|
||||
private String username;
|
||||
private String password;
|
||||
private String tokenEndpoint;
|
||||
private long tokenRefreshTimeOffset;
|
||||
private String deviceMgtServerUrl;
|
||||
private long cacheDuration;
|
||||
|
||||
private List<String> publisherPermissions = new ArrayList<>();
|
||||
private List<String> subscriberPermissions = new ArrayList<>();
|
||||
|
||||
private AuthorizationConfigurationManager() {
|
||||
|
||||
@ -59,51 +70,104 @@ public class AuthorizationConfigurationManager {
|
||||
}
|
||||
}
|
||||
|
||||
public String getAdminPermission() {
|
||||
return adminPermission;
|
||||
public List<String> getPublisherPermissions() {
|
||||
return publisherPermissions;
|
||||
}
|
||||
|
||||
public void setAdminPermission(String adminPermission) {
|
||||
if (adminPermission != null) {
|
||||
this.adminPermission = adminPermission;
|
||||
public void setPublisherPermission(String publisherPermission) {
|
||||
if (publisherPermission != null && !publisherPermission.isEmpty()) {
|
||||
this.publisherPermissions.add(publisherPermission);
|
||||
} else {
|
||||
logger.error("admin permission can't be null ");
|
||||
logger.error("MQTT publisher permission can't be empty ");
|
||||
}
|
||||
}
|
||||
|
||||
public String getMQTTPublisherScopeIdentifier() {
|
||||
return MQTTPublisherScopeIdentifier;
|
||||
public List<String> getSubscriberPermissions() {
|
||||
return subscriberPermissions;
|
||||
}
|
||||
|
||||
public void setMQTTPublisherScopeIdentifier(String MQTTPublisherScopeIdentifier) {
|
||||
if (MQTTPublisherScopeIdentifier != null) {
|
||||
this.MQTTPublisherScopeIdentifier = MQTTPublisherScopeIdentifier;
|
||||
public void setSubscriberPermission(String subscriberPermission) {
|
||||
if (subscriberPermission != null && !subscriberPermission.isEmpty()) {
|
||||
this.subscriberPermissions.add(subscriberPermission);
|
||||
} else {
|
||||
logger.error("MQTT publisher scope identifier can't be null ");
|
||||
logger.error("MQTT subscriber permissions can't be null ");
|
||||
}
|
||||
}
|
||||
|
||||
public String getMQTTSubscriberScopeIdentifier() {
|
||||
return MQTTSubscriberScopeIdentifier;
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setMQTTSubscriberScopeIdentifier(String MQTTSubscriberScopeIdentifier) {
|
||||
if (MQTTSubscriberScopeIdentifier != null) {
|
||||
this.MQTTSubscriberScopeIdentifier = MQTTSubscriberScopeIdentifier;
|
||||
public void setUsername(String username) {
|
||||
if (username != null && !username.isEmpty()) {
|
||||
this.username = username;
|
||||
} else {
|
||||
logger.error("MQTT subscriber scope identifier can't be null ");
|
||||
}
|
||||
logger.error("username can't be empty ");
|
||||
}
|
||||
|
||||
public String getDevicemgtScopeIdentifier() {
|
||||
return devicemgtScopeIdentifier;
|
||||
}
|
||||
|
||||
public void setDevicemgtScopeIdentifier(String devicemgtScopeIdentifier) {
|
||||
if (devicemgtScopeIdentifier != null) {
|
||||
this.devicemgtScopeIdentifier = devicemgtScopeIdentifier;
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
if (password != null && !password.isEmpty()) {
|
||||
this.password = password;
|
||||
} else {
|
||||
logger.error("Device management scope identifier can't be null ");
|
||||
logger.error("password can't be empty ");
|
||||
}
|
||||
}
|
||||
|
||||
public String getTokenEndpoint() {
|
||||
return tokenEndpoint;
|
||||
}
|
||||
|
||||
public void setTokenEndpoint(String tokenEndpoint) {
|
||||
if (tokenEndpoint != null && !tokenEndpoint.isEmpty()) {
|
||||
this.tokenEndpoint = tokenEndpoint;
|
||||
} else {
|
||||
logger.error("tokenEndpoint can't be empty ");
|
||||
}
|
||||
}
|
||||
|
||||
public long getTokenRefreshTimeOffset() {
|
||||
return tokenRefreshTimeOffset;
|
||||
}
|
||||
|
||||
public void setTokenRefreshTimeOffset(String tokenRefreshTimeOffset) {
|
||||
try {
|
||||
if (tokenRefreshTimeOffset != null && !tokenRefreshTimeOffset.isEmpty()) {
|
||||
this.tokenRefreshTimeOffset = Long.parseLong(tokenRefreshTimeOffset);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
logger.error("tokenRefreshTimeOffset is not a number(long)");
|
||||
}
|
||||
}
|
||||
|
||||
public String getDeviceMgtServerUrl() {
|
||||
return deviceMgtServerUrl;
|
||||
}
|
||||
|
||||
public void setDeviceMgtServerUrl(String deviceMgtServerUrl) {
|
||||
if (deviceMgtServerUrl != null && !deviceMgtServerUrl.isEmpty()) {
|
||||
this.deviceMgtServerUrl = deviceMgtServerUrl;
|
||||
} else {
|
||||
logger.error("deviceMgtServerUrl can't be empty ");
|
||||
}
|
||||
}
|
||||
|
||||
public long getCacheDuration() {
|
||||
return cacheDuration;
|
||||
}
|
||||
|
||||
public void setCacheDuration(String cacheDuration) {
|
||||
try {
|
||||
if (cacheDuration != null && !cacheDuration.isEmpty()) {
|
||||
this.cacheDuration = Long.parseLong(cacheDuration);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
this.cacheDuration = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,18 +184,32 @@ public class AuthorizationConfigurationManager {
|
||||
case CONNECTION_PERMISSION:
|
||||
setConnectionPermission(propertyValue);
|
||||
break;
|
||||
case ADMIN_PERMISSION:
|
||||
setAdminPermission(propertyValue);
|
||||
case MQTT_PUBLISHER_PERMISSION:
|
||||
setPublisherPermission(propertyValue);
|
||||
break;
|
||||
case MQTT_PUBLISHER_SCOPE_IDENTIFIER:
|
||||
setMQTTPublisherScopeIdentifier(propertyValue);
|
||||
case MQTT_SUBSCRIBER_PERMISSION:
|
||||
setSubscriberPermission(propertyValue);
|
||||
break;
|
||||
case MQTT_SUBSCRIBER_SCOPE_IDENTIFIER:
|
||||
setMQTTSubscriberScopeIdentifier(propertyValue);
|
||||
case CONNECTION_USERNAME:
|
||||
setUsername(propertyValue);
|
||||
break;
|
||||
case DEVICE_MGT_SCOPE_IDENTIFIER:
|
||||
setDevicemgtScopeIdentifier(propertyValue);
|
||||
case CONNECTION_PASSWORD:
|
||||
setPassword(propertyValue);
|
||||
break;
|
||||
case TOKEN_ENDPOINT:
|
||||
setTokenEndpoint(propertyValue);
|
||||
break;
|
||||
case TOKEN_REFRESH_TIME_OFFSET:
|
||||
setTokenRefreshTimeOffset(propertyValue);
|
||||
break;
|
||||
case DEVICE_MGT_SERVER_URL:
|
||||
setDeviceMgtServerUrl(propertyValue);
|
||||
break;
|
||||
case MQTT_CACHE_DURATION:
|
||||
setCacheDuration(propertyValue);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.util;
|
||||
|
||||
public class AuthorizationCacheKey {
|
||||
String tenantDomain;
|
||||
String deviceId;
|
||||
String deviceType;
|
||||
String username;
|
||||
|
||||
public AuthorizationCacheKey(String tenantDomain, String username, String deviceId, String deviceType) {
|
||||
this.username = username;
|
||||
this.tenantDomain = tenantDomain;
|
||||
this.deviceId = deviceId;
|
||||
this.deviceType = deviceType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = this.deviceType.hashCode();
|
||||
result = 31 * result + ("@" + this.deviceId + "@" + this.tenantDomain + "@" + this.username).hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return (obj instanceof AuthorizationCacheKey) && deviceType.equals(
|
||||
((AuthorizationCacheKey) obj).deviceType) && tenantDomain.equals(
|
||||
((AuthorizationCacheKey) obj).tenantDomain ) && deviceId.equals(
|
||||
((AuthorizationCacheKey) obj).deviceId) && username.equals(
|
||||
((AuthorizationCacheKey) obj).username);
|
||||
}
|
||||
|
||||
}
|
||||
@ -39,6 +39,18 @@
|
||||
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
|
||||
<artifactId>org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-jaxrs</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-gson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-jaxrs</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
@ -66,6 +78,12 @@
|
||||
<bundleDef>
|
||||
org.wso2.carbon.devicemgt-plugins:org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization:${carbon.devicemgt.plugins.version}
|
||||
</bundleDef>
|
||||
<bundleDef>
|
||||
io.github.openfeign:feign-core:${io.github.openfeign.version}
|
||||
</bundleDef>
|
||||
<bundleDef>
|
||||
io.github.openfeign:feign-gson:${io.github.openfeign.version}
|
||||
</bundleDef>
|
||||
</bundles>
|
||||
<importFeatures>
|
||||
<importFeatureDef>org.wso2.carbon.core.server:4.4.9</importFeatureDef>
|
||||
|
||||
@ -68,6 +68,16 @@
|
||||
<groupId>com.jayway.jsonpath</groupId>
|
||||
<artifactId>json-path</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-jaxrs</artifactId>
|
||||
<version>${io.github.openfeign.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-gson</artifactId>
|
||||
<version>${io.github.openfeign.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
@ -92,7 +102,7 @@
|
||||
<outputDirectory>
|
||||
${project.build.directory}/maven-shared-archive-resources/webapps/
|
||||
</outputDirectory>
|
||||
<destFileName>secured-outputui.war</destFileName>
|
||||
<destFileName>secured-websocket.war</destFileName>
|
||||
</artifactItem>
|
||||
</artifactItems>
|
||||
</configuration>
|
||||
@ -180,6 +190,12 @@
|
||||
<bundleDef>
|
||||
com.jayway.jsonpath:json-path
|
||||
</bundleDef>
|
||||
<bundleDef>
|
||||
io.github.openfeign:feign-core:${io.github.openfeign.version}
|
||||
</bundleDef>
|
||||
<bundleDef>
|
||||
io.github.openfeign:feign-gson:${io.github.openfeign.version}
|
||||
</bundleDef>
|
||||
</bundles>
|
||||
<importFeatures>
|
||||
<importFeatureDef>
|
||||
|
||||
@ -35,5 +35,16 @@
|
||||
</Authenticator>
|
||||
|
||||
<!--Authorizer holds the information of the authorizer that is used authorize a connection.-->
|
||||
<Authorizer class="org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.DeviceAuthorizer"></Authorizer>
|
||||
<Authorizer class="org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.DeviceAuthorizer">
|
||||
<Properties>
|
||||
<!--websocket connection permissions which are validated for grouping (can have multiple permission.)-->
|
||||
<Property name="statsPermission">/permission/device-mgt/user/groups/device_monitor</Property>
|
||||
<Property name="username">admin</Property>
|
||||
<Property name="password">admin</Property>
|
||||
<Property name="tokenEndpoint">https://localhost:9443/oauth2</Property>
|
||||
<!--offset time from expiry time to trigger refresh call (in seconds)-->
|
||||
<Property name="tokenRefreshTimeOffset">100</Property>
|
||||
<Property name="deviceMgtServerUrl">https://localhost:9443</Property>
|
||||
</Properties>
|
||||
</Authorizer>
|
||||
</WebsocketValidationConfigs>
|
||||
24
pom.xml
24
pom.xml
@ -239,6 +239,11 @@
|
||||
<artifactId>org.wso2.carbon.ndatasource.core</artifactId>
|
||||
<version>${carbon.kernel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>javax.cache.wso2</artifactId>
|
||||
<version>${carbon.kernel.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Device Management Core dependencies -->
|
||||
<dependency>
|
||||
@ -1155,6 +1160,21 @@
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>${commons.lang.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-core</artifactId>
|
||||
<version>${io.github.openfeign.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-jaxrs</artifactId>
|
||||
<version>${io.github.openfeign.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-gson</artifactId>
|
||||
<version>${io.github.openfeign.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
@ -1317,6 +1337,10 @@
|
||||
|
||||
<!-- MB Features -->
|
||||
<carbon.messaging.version>3.1.11</carbon.messaging.version>
|
||||
|
||||
<!--Feign Version-->
|
||||
<io.github.openfeign.version>9.3.1</io.github.openfeign.version>
|
||||
<javax.ws.rs.jsr311-api.version>[1.1.0, 2.0.0)</javax.ws.rs.jsr311-api.version>
|
||||
</properties>
|
||||
|
||||
<scm>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user