Commit 3dc08349 authored by Hema Vishnu Pola [Microsoft]'s avatar Hema Vishnu Pola [Microsoft]
Browse files

Merge branch 'users/komakkar/EventGridAuth' into 'master'

Authz addition for Event Grid

See merge request !57
parents 3a37042e 91b0b0f3
Pipeline #24348 passed with stages
in 27 minutes and 41 seconds
......@@ -538,6 +538,7 @@ The following software have components provided under the terms of this license:
- Java Client Runtime for AutoRest (from https://github.com/Azure/autorest-clientruntime-for-java)
- Java JWT (from http://www.jwt.io)
- Java JWT (from http://www.jwt.io)
- Java JWT (from http://www.jwt.io)
- Lucene Core (from )
- Microsoft Application Insights Java SDK Core (from https://github.com/Microsoft/ApplicationInsights-Java)
- Microsoft Application Insights Java SDK Spring Boot starter (from https://github.com/Microsoft/ApplicationInsights-Java)
......
......@@ -87,6 +87,11 @@
<artifactId>notification-core</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.3.0</version>
</dependency>
<!--
Override the spring-boot version of these dependencies to the ones
......
......@@ -40,6 +40,9 @@ public class AppProperties implements IAppProperties {
@Value("${aad.oboApi}")
private String aadOboAPI;
@Value("${aad.eventGridId}")
private String eventGridId;
@Autowired
private SecretClient secretClient;
......@@ -53,6 +56,10 @@ public class AppProperties implements IAppProperties {
return aadOboAPI;
}
public String getEventGridId() {
return eventGridId;
}
public String getAuthorizeAPI() {
return this.authorizeAPI;
}
......
......@@ -14,6 +14,9 @@
package org.opengroup.osdu.notification.provider.azure.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
import org.opengroup.osdu.notification.provider.interfaces.IServiceAccountValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
......@@ -21,21 +24,29 @@ import org.springframework.stereotype.Service;
@Service
public class AzureServiceAccountValidatorImpl implements IServiceAccountValidator {
private final static String APP_ID_CLAIM = "appid";
@Autowired
AppProperties appProperties;
@Autowired
JaxRsDpsLog logger;
@Override
public boolean isValidPublisherServiceAccount(String token) {
return isValidServiceAccount(token, this.appProperties.getAadClientID());
return isValidServiceAccount(token, this.appProperties.getEventGridId());
}
@Override
public boolean isValidServiceAccount(String token, String userIdentity, String... audiences) {
// TODO : find out if this will be required to authZ,
// when we are are authZ through Entitlement Service.
//
// Tracking through a issue.
DecodedJWT jwt = JWT.decode(token);
String appIdClaim = jwt.getClaim(APP_ID_CLAIM).asString();
if(appIdClaim!= null && appIdClaim.equals(userIdentity)) {
logger.info("PubSub authorized");
return true;
}
return false;
}
}
......@@ -21,15 +21,16 @@ import com.microsoft.aad.adal4j.ClientCredential;
import org.apache.http.HttpStatus;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.opengroup.osdu.core.common.model.search.IdToken;
import org.opengroup.osdu.core.common.model.tenant.TenantInfo;
import org.opengroup.osdu.core.common.provider.interfaces.IJwtCache;
import org.opengroup.osdu.core.common.provider.interfaces.ITenantFactory;
import org.opengroup.osdu.core.common.util.IServiceAccountJwtClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.net.MalformedURLException;
import java.util.concurrent.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@Component
public class ServiceAccountJwtAzureClientImpl implements IServiceAccountJwtClient {
......@@ -37,24 +38,16 @@ public class ServiceAccountJwtAzureClientImpl implements IServiceAccountJwtClien
@Autowired
private AppProperties config;
@Autowired
private ITenantFactory tenantInfoServiceProvider;
@Autowired
private IJwtCache tenantJwtCache;
public String getIdToken(String tenantName) {
TenantInfo tenant = this.tenantInfoServiceProvider.getTenantInfo(tenantName);
if (tenant == null) {
throw new AppException(HttpStatus.SC_BAD_REQUEST, "Invalid tenant Name", "Invalid tenant Name from azure");
}
String ACCESS_TOKEN = "";
ExecutorService service = null;
try {
// TODO : Refactor to move ID token form Common.Core.model.search to Common.core
IdToken cachedToken = (IdToken) this.tenantJwtCache.get(tenant.getName());
IdToken cachedToken = (IdToken) this.tenantJwtCache.get(tenantName);
if ((cachedToken != null) && !IdToken.refreshToken(cachedToken)) {
return "Bearer " + cachedToken.getTokenValue();
......@@ -65,7 +58,7 @@ public class ServiceAccountJwtAzureClientImpl implements IServiceAccountJwtClien
ACCESS_TOKEN = getAccessToken(service);
IdToken idToken = IdToken.builder().tokenValue(ACCESS_TOKEN).expirationTimeMillis(JWT.decode(ACCESS_TOKEN).getExpiresAt().getTime()).build();
this.tenantJwtCache.put(tenant.getName(), idToken);
this.tenantJwtCache.put(tenantName, idToken);
} finally {
if(service != null) {
service.shutdown();
......
......@@ -30,6 +30,7 @@ azure.activedirectory.session-stateless=true
aad.oboApi=${aad_client_id}
azure.application-insights.instrumentation-key=${appinsights_key}
aad.eventGridId=4962773b-9cdb-44cf-a8bf-237846a00ab7
# Azure CosmosDB configuration
azure.cosmosdb.database=${cosmosdb_database}
......
......@@ -14,23 +14,24 @@
package org.opengroup.osdu.notification.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import org.opengroup.osdu.notification.provider.azure.util.AppProperties;
import org.opengroup.osdu.notification.provider.azure.util.AzureServiceAccountValidatorImpl;
import java.io.UnsupportedEncodingException;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
public class AzureServiceAccountValidatorImplTest {
private static String invalidAADClientID = "testInvalidAADClientID";
private static String invalidJWT = "invalidJWT";
private static String eventGridId = "eventgridid";
@Mock
private AppProperties appProperties;
......@@ -42,16 +43,19 @@ public class AzureServiceAccountValidatorImplTest {
@Before
public void setup() {
initMocks(this);
when(this.appProperties.getAadClientID()).thenReturn(invalidAADClientID);
when(this.appProperties.getEventGridId()).thenReturn(eventGridId);
}
@Test
public void should_returnFalse_isValidServiceAccount() {
public void should_returnFalse_isValidServiceAccount() throws UnsupportedEncodingException {
// Set Up
boolean expected = false;
Algorithm algorithm = Algorithm.HMAC256("secret");
String token = JWT.create()
.withIssuer("auth0")
.sign(algorithm);
// Act
boolean observed = this.sut.isValidPublisherServiceAccount(invalidJWT);
boolean observed = this.sut.isValidPublisherServiceAccount(token);
// Assert
Assert.assertEquals(expected, observed);
......
......@@ -26,8 +26,6 @@ import org.mockito.junit.MockitoJUnitRunner;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.opengroup.osdu.core.common.model.search.IdToken;
import org.opengroup.osdu.core.common.model.tenant.TenantInfo;
import org.opengroup.osdu.core.common.provider.interfaces.ITenantFactory;
import org.opengroup.osdu.notification.provider.azure.cache.JwtCache;
import org.opengroup.osdu.notification.provider.azure.util.AppProperties;
import org.opengroup.osdu.notification.provider.azure.util.ServiceAccountJwtAzureClientImpl;
......@@ -36,8 +34,8 @@ import java.util.concurrent.ExecutorService;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.MockitoAnnotations.initMocks;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
@RunWith(MockitoJUnitRunner.class)
public class ServiceAccountClientImplTest {
......@@ -45,12 +43,6 @@ public class ServiceAccountClientImplTest {
final String tenantName = "Test Tenant";
final String validToken = "validToken";
@Mock
private ITenantFactory tenantInfoServiceProvider;
@Mock
private TenantInfo tenantInfo;
@Mock
private IdToken idToken;
......@@ -73,29 +65,9 @@ public class ServiceAccountClientImplTest {
@Before
public void setup() {
initMocks(this);
when(tenantInfo.getName()).thenReturn(tenantName);
when(this.tenantInfoServiceProvider.getTenantInfo(tenantName)).thenReturn(tenantInfo);
idToken = IdToken.builder().tokenValue(validToken).expirationTimeMillis(System.currentTimeMillis() + 10000000L).build();
}
@Test
public void should_throwAppException_getIdTokenTest() {
// Set up
when(this.tenantInfoServiceProvider.getTenantInfo(tenantName)).thenReturn(null);
try {
// Act
sut.getIdToken(tenantName);
// Assert
fail("Should throw exception");
} catch (AppException e) {
Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, e.getError().getCode());
Assert.assertEquals("Invalid tenant Name from azure", e.getError().getMessage());
} catch (Exception e) {
fail("Should not throw this exception" + e.getMessage());
}
}
@Test
public void should_getTokenFromCache_getIdTokenTest() {
// SetUp
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment