Skip to content
Snippets Groups Projects
Commit a3a44e4d authored by Vibhuti Sharma [Microsoft]'s avatar Vibhuti Sharma [Microsoft]
Browse files

initial commit

parent a32067fa
No related branches found
No related tags found
1 merge request!83Using Istio auth in Partition Service
Checking pipeline status
......@@ -16,6 +16,7 @@ package org.opengroup.osdu.partition.provider.azure.security;
import com.azure.spring.autoconfigure.aad.AADAppRoleStatelessAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
......@@ -25,8 +26,10 @@ import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
// TODO: check if this class can be safely deleted.
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@ConditionalOnProperty(value = "azure.istio.auth.enabled", havingValue = "false", matchIfMissing = false)
public class AADSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
......
package org.opengroup.osdu.partition.provider.azure.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@ConditionalOnProperty(value = "azure.istio.auth.enabled", havingValue = "true", matchIfMissing = true)
public class AzureIstioSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AzureIstioSecurityFilter appRoleAuthFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().disable()
.csrf().disable()
.addFilterBefore(appRoleAuthFilter, UsernamePasswordAuthenticationFilter.class);
}
}
package org.opengroup.osdu.partition.provider.azure.security;
import com.azure.spring.autoconfigure.aad.UserPrincipal;
import com.nimbusds.jwt.JWTClaimsSet;
import net.minidev.json.JSONArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;
import static org.springframework.util.StringUtils.hasText;
@Component
@ConditionalOnProperty(value = "azure.istio.auth.enabled", havingValue = "true", matchIfMissing = true)
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.
* @param servletRequest Request object.
* @param servletResponse Response object.
* @param filterChain Filter Chain object.
* @throws IOException
* @throws ServletException
*/
@Override
protected void doFilterInternal(final HttpServletRequest servletRequest, final HttpServletResponse servletResponse, final FilterChain filterChain) throws ServletException, IOException {
final String istioPayload = servletRequest.getHeader(X_ISTIO_CLAIMS_PAYLOAD);
LOGGER.info(String.format("Received headers list: %s", Collections.list(servletRequest.getHeaderNames())));
try {
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.
// TODO: check where the claims were being set in case of ADSecurityConfig
SecurityContextHolder
.getContext()
.setAuthentication(
// TODO: check if aadIssuedBearerToken parameter should be null here
new PreAuthenticatedAuthenticationToken(
new UserPrincipal(null,null, claimsSet),
null,
rolesToGrantedAuthorities(roles)
));
} else {
SecurityContextHolder
.getContext()
.setAuthentication(
new PreAuthenticatedAuthenticationToken(
null, null, null
));
}
} catch (ParseException ex) {
LOGGER.error("Failed to initialize UserPrincipal.", ex);
throw new ServletException(ex);
}
try {
filterChain.doFilter(servletRequest, servletResponse);
} finally {
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());
}
}
......@@ -16,6 +16,9 @@ azure.activedirectory.client-id=${aad_client_id}
azure.activedirectory.AppIdUri=api://${azure.activedirectory.client-id}
azure.activedirectory.session-stateless=true
# Istio
azure.istio.auth.enabled=${azure_istioauth_enabled}
# Azure KeyVault configuration
azure.keyvault.url=${KEYVAULT_URI}
......
......@@ -34,7 +34,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {HomeController.class,
@SpringBootTest(properties = {"azure.istio.auth.enabled=true"}, classes = {HomeController.class,
PartitionApi.class,
AADSecurityConfig.class,
AADAppRoleStatelessAuthenticationFilter.class})
......
......@@ -39,7 +39,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@RunWith(SpringRunner.class)
@PrepareForTest(SecurityContextHolder.class)
@SpringBootTest(classes = {WhoamiController.class, AADSecurityConfig.class,
@SpringBootTest(properties = {"azure.istio.auth.enabled=true"}, classes = {WhoamiController.class, AADSecurityConfig.class,
AADAppRoleStatelessAuthenticationFilter.class})
@WebAppConfiguration
public class WhoamiControllerTest {
......
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