OAuthRequestInterceptor.java
/*
* Copyright (c) 2018, 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.extension.siddhi.device.client;
import feign.Feign;
import feign.Logger;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import feign.auth.BasicAuthRequestInterceptor;
import feign.gson.GsonDecoder;
import feign.gson.GsonEncoder;
import feign.jaxrs.JAXRSContract;
import feign.okhttp.OkHttpClient;
import feign.slf4j.Slf4jLogger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.extension.siddhi.device.client.configs.SiddhiExtensionConfigReader;
import org.wso2.extension.siddhi.device.client.dto.OAuthApplication;
import org.wso2.extension.siddhi.device.client.dto.RegistrationProfile;
import org.wso2.extension.siddhi.device.client.exception.APIMClientOAuthException;
import org.wso2.extension.siddhi.device.client.services.DCRService;
import org.wso2.extension.siddhi.device.utils.ClientUtils;
import org.wso2.extension.siddhi.device.utils.DeviceUtils;
/**
* This is a request interceptor to add oauth token header.
*/
public class OAuthRequestInterceptor implements RequestInterceptor {
private static final String APPLICATION_NAME = "siddhi_extension_client";
private static final String REQUIRED_SCOPES = "perm:devices:operations";
private static final String[] API_TAGS = {"device_management"};
private DCRService dcrService;
private static OAuthApplication oAuthApplication;
private static final Log log = LogFactory.getLog(OAuthRequestInterceptor.class);
/**
* Creates an interceptor that authenticates all requests.
*/
public OAuthRequestInterceptor() {
String username = SiddhiExtensionConfigReader.getInstance().getConfig().getUsername();
String password = SiddhiExtensionConfigReader.getInstance().getConfig().getPassword();
dcrService = Feign.builder().client(new OkHttpClient(ClientUtils.getSSLClient())).logger(new Slf4jLogger())
.logLevel(Logger.Level.FULL)
.requestInterceptor(new BasicAuthRequestInterceptor(username, password))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(DCRService.class, ClientUtils.replaceProperties(
SiddhiExtensionConfigReader.getInstance().getConfig().getDcrEndpoint()));
}
@Override
public void apply(RequestTemplate template) {
if (oAuthApplication == null) {
RegistrationProfile registrationProfile = new RegistrationProfile();
registrationProfile.setApiApplicationName(APPLICATION_NAME);
registrationProfile.setIsAllowedToAllDomains(true);
registrationProfile.setTags(API_TAGS);
oAuthApplication = dcrService.register(registrationProfile);
}
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
try {
String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm().getRealmConfiguration().getAdminUserName();
if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {
username = username + "@" + tenantDomain;
}
JWTClient jwtClient = DeviceUtils.getJWTClientManagerService().getJWTClient();
AccessTokenInfo tenantBasedAccessTokenInfo = jwtClient.getAccessToken(oAuthApplication.getClientId(),
oAuthApplication.getClientSecret(), username, REQUIRED_SCOPES);
if (tenantBasedAccessTokenInfo.getAccessToken() != null) {
String headerValue = "Bearer " + tenantBasedAccessTokenInfo.getAccessToken();
template.header("Authorization", headerValue);
}
} catch (JWTClientException e) {
String msg = "Failed to retrieve oauth token using jwt";
log.error(msg, e);
throw new APIMClientOAuthException(msg, e);
} catch (UserStoreException e) {
String msg = "Unable to retrieve realm config for tenant " + tenantDomain;
log.error(msg, e);
throw new APIMClientOAuthException(msg, e);
}
}
}