Skip to content
Snippets Groups Projects
Commit 749a8e2c authored by Aman Verma's avatar Aman Verma Committed by Nishant Vidyasagar
Browse files

Update AzureIstioSecurityFilter to exclude roles when setting authentication

parent dceee9a3
No related branches found
No related tags found
1 merge request!724Update AzureIstioSecurityFilter to exclude roles when setting authentication
......@@ -34,8 +34,6 @@ public class AzureIstioSecurityFilter extends OncePerRequestFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(AzureIstioSecurityFilter.class);
private static final String X_ISTIO_CLAIMS_PAYLOAD = "x-payload";
private static final JSONArray DEFAULT_ROLE_CLAIM = new JSONArray().appendElement("USER");
private static final String ROLE_PREFIX = "ROLE_";
/**
* Filter logic.
......@@ -55,10 +53,6 @@ public class AzureIstioSecurityFilter extends OncePerRequestFilter {
if (hasText(istioPayload)) {
JWTClaimsSet claimsSet = JWTClaimsSet.parse(new String(Base64.getDecoder().decode(istioPayload)));
final JSONArray roles = Optional.ofNullable((JSONArray) claimsSet.getClaims().get("roles"))
.filter(r -> !r.isEmpty())
.orElse(DEFAULT_ROLE_CLAIM);
// By default the authenticated is set to true as part PreAuthenticatedAuthenticationToken constructor.
SecurityContextHolder
.getContext()
......@@ -66,7 +60,7 @@ public class AzureIstioSecurityFilter extends OncePerRequestFilter {
new PreAuthenticatedAuthenticationToken(
new UserPrincipal(null,null, claimsSet),
null,
rolesToGrantedAuthorities(roles)
null
));
} else {
SecurityContextHolder
......@@ -86,16 +80,4 @@ public class AzureIstioSecurityFilter extends OncePerRequestFilter {
SecurityContextHolder.clearContext();
}
}
/**
* To return roles.
* @param roles Request Object.
* @return set representation of roles.
*/
protected Set<SimpleGrantedAuthority> rolesToGrantedAuthorities(final JSONArray roles) {
return roles.stream()
.filter(Objects::nonNull)
.map(s -> new SimpleGrantedAuthority(ROLE_PREFIX + s))
.collect(Collectors.toSet());
}
}
package org.opengroup.osdu.schema.security;
import com.azure.spring.cloud.autoconfigure.implementation.aad.filter.UserPrincipal;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collections;
import java.util.Enumeration;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
public class AzureIstioSecurityFilterTest {
private static final String X_ISTIO_CLAIMS_PAYLOAD = "x-payload";
private static final String ISTIO_PAYLOAD = "{\"aud\":\"aud1\",\"iss\":\"https://iss1\",\"ver\":\"1.0\",\"roles\":[\"role1\",\"role2\",\"role3\"]}";
private static final String INVALID_ISTIO_PAYLOAD = "\"aud\":\"aud1\",\"iss\":\"https://iss1\",\"ver\":\"1.0\"";
@InjectMocks
private AzureIstioSecurityFilter azureIstioSecurityFilter;
@Test
public void should_setCorrectAuthentication_when_istioPayloadExists() throws IOException, ServletException {
ArgumentCaptor<PreAuthenticatedAuthenticationToken> authCaptor = ArgumentCaptor.forClass(PreAuthenticatedAuthenticationToken.class);
HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
HttpServletResponse httpServletResponse = mock(HttpServletResponse.class);
SecurityContext securityContext = Mockito.mock(SecurityContext.class);
FilterChain filterChain = Mockito.mock(FilterChain.class);
Enumeration<String> headerNames = Collections.enumeration(Arrays.asList("Content-Type", "header1"));
SecurityContextHolder.setContext(securityContext);
when(httpServletRequest.getHeaderNames()).thenReturn(headerNames);
when(httpServletRequest.getHeader(X_ISTIO_CLAIMS_PAYLOAD)).thenReturn(new String(Base64.getEncoder().encode(ISTIO_PAYLOAD.getBytes())));
azureIstioSecurityFilter.doFilter(httpServletRequest, httpServletResponse, filterChain);
verify(securityContext).setAuthentication(authCaptor.capture());
PreAuthenticatedAuthenticationToken auth = authCaptor.getValue();
assert_UserPrincipal((UserPrincipal) auth.getPrincipal());
assertNull(auth.getCredentials());
assertEquals(Collections.EMPTY_LIST, auth.getAuthorities());
verify(filterChain).doFilter(httpServletRequest, httpServletResponse);
}
@Test
public void should_setCorrectAuthentication_when_istioPayloadNotExists() throws IOException, ServletException {
ArgumentCaptor<PreAuthenticatedAuthenticationToken> authCaptor = ArgumentCaptor.forClass(PreAuthenticatedAuthenticationToken.class);
HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
HttpServletResponse httpServletResponse = mock(HttpServletResponse.class);
SecurityContext securityContext = Mockito.mock(SecurityContext.class);
FilterChain filterChain = Mockito.mock(FilterChain.class);
Enumeration<String> headerNames = Collections.enumeration(Arrays.asList("Content-Type", "header1"));
SecurityContextHolder.setContext(securityContext);
when(httpServletRequest.getHeaderNames()).thenReturn(headerNames);
when(httpServletRequest.getHeader(X_ISTIO_CLAIMS_PAYLOAD)).thenReturn("");
azureIstioSecurityFilter.doFilter(httpServletRequest, httpServletResponse, filterChain);
verify(securityContext).setAuthentication(authCaptor.capture());
PreAuthenticatedAuthenticationToken auth = authCaptor.getValue();
assertNull(auth.getPrincipal());
assertNull(auth.getCredentials());
assertEquals(Collections.EMPTY_LIST, auth.getAuthorities());
verify(filterChain).doFilter(httpServletRequest, httpServletResponse);
}
@Test
public void should_throwAppException500_when_istioPayloadInvalidJsonData() throws IOException, ServletException {
ArgumentCaptor<PreAuthenticatedAuthenticationToken> authCaptor = ArgumentCaptor.forClass(PreAuthenticatedAuthenticationToken.class);
HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
HttpServletResponse httpServletResponse = mock(HttpServletResponse.class);
SecurityContext securityContext = Mockito.mock(SecurityContext.class);
FilterChain filterChain = Mockito.mock(FilterChain.class);
Enumeration<String> headerNames = Collections.enumeration(Arrays.asList("Content-Type", "header1"));
SecurityContextHolder.setContext(securityContext);
when(httpServletRequest.getHeaderNames()).thenReturn(headerNames);
when(httpServletRequest.getHeader(X_ISTIO_CLAIMS_PAYLOAD)).thenReturn(new String(Base64.getEncoder().encode(INVALID_ISTIO_PAYLOAD.getBytes())));
AppException appException = assertThrows(AppException.class,
() -> azureIstioSecurityFilter.doFilter(httpServletRequest, httpServletResponse, filterChain));
assertEquals(500, appException.getError().getCode());
assertTrue(appException.getError().getMessage().contains("Invalid JSON"));
}
private void assert_UserPrincipal(UserPrincipal principal) {
assertEquals(4, principal.getClaims().size());
assertEquals(Arrays.asList("aud1"), principal.getClaims().get("aud"));
assertEquals("https://iss1", principal.getClaims().get("iss"));
assertEquals("1.0", principal.getClaims().get("ver"));
assertEquals("[role1, role2, role3]", principal.getClaims().get("roles").toString());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment