Commit b38f1f2b authored by Sherman Yang's avatar Sherman Yang
Browse files

Merge branch 'entitlement' into 'master'

Enhance and enable AuthenticationRequestFilter from AKS to enforce entitlements

See merge request !10
parents 05dc8fad bd0b4f26
Pipeline #13892 passed with stages
in 11 minutes and 48 seconds
...@@ -8,7 +8,6 @@ import org.opengroup.osdu.core.common.model.entitlements.EntitlementsException; ...@@ -8,7 +8,6 @@ import org.opengroup.osdu.core.common.model.entitlements.EntitlementsException;
import org.opengroup.osdu.core.common.model.entitlements.Groups; import org.opengroup.osdu.core.common.model.entitlements.Groups;
import org.opengroup.osdu.core.common.model.http.DpsHeaders; import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.crs.util.AppException; import org.opengroup.osdu.crs.util.AppException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.lang.NonNull; import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
...@@ -38,7 +37,7 @@ public class AuthenticationRequestFilter extends OncePerRequestFilter { ...@@ -38,7 +37,7 @@ public class AuthenticationRequestFilter extends OncePerRequestFilter {
private final String entitlementsUrl; private final String entitlementsUrl;
private final HandlerExceptionResolver handlerExceptionResolver; private final HandlerExceptionResolver handlerExceptionResolver;
public AuthenticationRequestFilter(@Value("${osdu.entitlement.url}") String entitlementsUrl, public AuthenticationRequestFilter(String entitlementsUrl,
HandlerExceptionResolver handlerExceptionResolver) { HandlerExceptionResolver handlerExceptionResolver) {
this.entitlementsUrl = entitlementsUrl; this.entitlementsUrl = entitlementsUrl;
this.handlerExceptionResolver = handlerExceptionResolver; this.handlerExceptionResolver = handlerExceptionResolver;
......
...@@ -11,36 +11,38 @@ stages: ...@@ -11,36 +11,38 @@ stages:
- group: 'Azure Target Env - ${{environment.name}}' - group: 'Azure Target Env - ${{environment.name}}'
jobs: jobs:
- job: MavenPackageAndPublishArtifacts - deployment: MavenPackageAndPublishArtifacts
displayName: Build Package and Publish Artifacts displayName: Build Package and Publish Artifacts
environment: ${{ environment.name }}
pool: $(AGENT_POOL) pool: $(AGENT_POOL)
strategy:
steps: runOnce:
- download: none deploy:
steps:
- checkout: self - download: none
path: s
- checkout: self
- task: AzureCLI@1 path: s
displayName: 'Docker Build + ACR Push'
# condition: and(succeeded(), eq('${{ parameters.providerName }}', 'Azure')) - task: AzureCLI@1
env: displayName: 'Docker Build + ACR Push'
IMAGE: $(CONTAINER_REGISTRY_NAME).azurecr.io/crs-catalog-data:v2 # condition: and(succeeded(), eq('${{ parameters.providerName }}', 'Azure'))
inputs: env:
azureSubscription: '$(SERVICE_CONNECTION_NAME)' IMAGE: $(CONTAINER_REGISTRY_NAME).azurecr.io/crs-catalog-data:v2
addSpnToEnvironment: true inputs:
scriptLocation: inlineScript azureSubscription: '$(SERVICE_CONNECTION_NAME)'
inlineScript: | addSpnToEnvironment: true
#!/usr/bin/env bash scriptLocation: inlineScript
set -euo pipefail inlineScript: |
#!/usr/bin/env bash
curl -L https://aka.ms/acr/installaad/bash | /bin/bash set -euo pipefail
echo "Logging in to the ACR Registry"
echo "------------------------------------" curl -L https://aka.ms/acr/installaad/bash | /bin/bash
az acr login -n $(CONTAINER_REGISTRY_NAME) echo "Logging in to the ACR Registry"
echo "------------------------------------"
pushd data az acr login -n $(CONTAINER_REGISTRY_NAME)
docker build -t $IMAGE .
docker push $IMAGE pushd data
popd docker build -t $IMAGE .
docker push $IMAGE
popd
...@@ -38,7 +38,7 @@ spec: ...@@ -38,7 +38,7 @@ spec:
- containerPort: 80 - containerPort: 80
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /api/crs/catalog/_ah/readiness_check path: /api/crs/catalog/swagger-ui.html
port: 80 port: 80
volumeMounts: volumeMounts:
- name: azure-keyvault - name: azure-keyvault
......
...@@ -61,6 +61,9 @@ stages: ...@@ -61,6 +61,9 @@ stages:
testCoreMavenOptions: '' testCoreMavenOptions: ''
skipDeploy: ${{ variables.SKIP_DEPLOY }} skipDeploy: ${{ variables.SKIP_DEPLOY }}
skipTest: 'true' skipTest: 'true'
runPythonTest: 'true'
testPythonFilePath: 'testing/catalog_test_azure'
testPythonFile: 'run-integration-tests.sh'
providers: providers:
- name: Azure - name: Azure
environments: ['dev'] environments: ['dev']
package org.opengroup.osdu.crs.security; package org.opengroup.osdu.crs.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.opengroup.osdu.core.common.model.http.AppError;
import org.opengroup.osdu.crs.middleware.AuthenticationRequestFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 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.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.servlet.HandlerExceptionResolver;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@EnableWebSecurity @EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) @EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter { public class SecurityConfig extends WebSecurityConfigurerAdapter implements AccessDeniedHandler, AuthenticationEntryPoint {
private AuthenticationRequestFilter authFilter;
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
private static final String[] AUTH_WHITELIST = { private static final String[] AUTH_WHITELIST = {
"/", "/",
...@@ -24,14 +46,54 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { ...@@ -24,14 +46,54 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
"/csrf" "/csrf"
}; };
//AuthenticationRequestFilter is not a recognized bean, so construct it manually
public SecurityConfig(@Value("${ENTITLEMENT_URL}") String entitlementsUrl, HandlerExceptionResolver handlerExceptionResolver) {
authFilter = new AuthenticationRequestFilter(entitlementsUrl, handlerExceptionResolver);
}
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
.cors() .cors()
.and() .and()
.csrf().disable() .csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and() .and()
.authorizeRequests().antMatchers(AUTH_WHITELIST).permitAll(); .authorizeRequests().antMatchers(AUTH_WHITELIST).permitAll()
.and()
.addFilterBefore(authFilter, UsernamePasswordAuthenticationFilter.class);
} }
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers(AUTH_WHITELIST);
}
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
writeUnauthorizedError(httpServletResponse);
}
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
writeUnauthorizedError(httpServletResponse);
}
private static void writeUnauthorizedError(HttpServletResponse response) throws IOException {
AppError appError = AppError.builder()
.code(HttpStatus.UNAUTHORIZED.value())
.message("The user is not authorized to perform this action")
.reason("Unauthorized")
.build();
String body = OBJECT_MAPPER.writeValueAsString(appError);
PrintWriter out = response.getWriter();
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
out.print(body);
out.flush();
}
} }
Supports Markdown
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