add CAS authentication #138

Merged
hsh-michaelhoennig merged 24 commits from feature/add-cas-authentication into master 2024-12-23 12:49:46 +01:00
6 changed files with 30 additions and 8 deletions
Showing only changes of commit 9ed2b79fe3 - Show all commits

View File

@ -73,6 +73,8 @@ If you have at least Docker and the Java JDK installed in appropriate versions a
gw bootRun # compiles and runs the application on localhost:8080 gw bootRun # compiles and runs the application on localhost:8080
FIXME: use bin/hsadmin-ng for the following commands
# the following command should reply with "pong": # the following command should reply with "pong":
curl -f http://localhost:8080/api/ping curl -f http://localhost:8080/api/ping

View File

@ -13,10 +13,10 @@ import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@Component @Component
public class CasAuthenticationFilter implements Filter { public class AuthenticationFilter implements Filter {
@Autowired @Autowired
private CasAuthenticator casAuthenticator; private Authenticator authenticator;
@Override @Override
@SneakyThrows @SneakyThrows
@ -25,7 +25,7 @@ public class CasAuthenticationFilter implements Filter {
final var httpResponse = (HttpServletResponse) response; final var httpResponse = (HttpServletResponse) response;
try { try {
final var currentSubject = casAuthenticator.authenticate(httpRequest); final var currentSubject = authenticator.authenticate(httpRequest);
final var authenticatedRequest = new AuthenticatedHttpServletRequestWrapper(httpRequest); final var authenticatedRequest = new AuthenticatedHttpServletRequestWrapper(httpRequest);
authenticatedRequest.addHeader("current-subject", currentSubject); authenticatedRequest.addHeader("current-subject", currentSubject);

View File

@ -4,6 +4,7 @@ import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
@ -13,6 +14,7 @@ import org.springframework.web.client.RestTemplate;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
@Primary
@Service @Service
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor

View File

@ -2,6 +2,7 @@ package net.hostsharing.hsadminng.config;
import java.util.Map; import java.util.Map;
import com.github.tomakehurst.wiremock.WireMockServer;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -14,10 +15,13 @@ import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.TestPropertySource;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(properties = {"management.port=0", "server.port=0", "hsadminng.cas.server-url=fake"}) @TestPropertySource(properties = {"management.port=0", "server.port=0", "hsadminng.cas.server-url=http://localhost:8088/cas"})
// IMPORTANT: To test prod config, do not use test profile! // IMPORTANT: To test prod config, do not use test profile!
class WebSecurityConfigIntegrationTest { class WebSecurityConfigIntegrationTest {
@ -30,11 +34,27 @@ class WebSecurityConfigIntegrationTest {
@Autowired @Autowired
private TestRestTemplate restTemplate; private TestRestTemplate restTemplate;
@Autowired
private WireMockServer wireMockServer;
@Test @Test
public void shouldSupportPingEndpoint() { public void shouldSupportPingEndpoint() {
// given
wireMockServer.stubFor(get(urlEqualTo("/cas/p3/serviceValidate?service=http://localhost:8080/api&ticket=test-user"))
.willReturn(aResponse()
.withStatus(200)
.withBody("""
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationSuccess>
<cas:user>test-user</cas:user>
</cas:authenticationSuccess>
</cas:serviceResponse>
""")));
// fake Authorization header // fake Authorization header
final var headers = new HttpHeaders(); final var headers = new HttpHeaders();
headers.set("Authorization", "test"); headers.set("Authorization", "test-user");
// http request // http request
final var result = restTemplate.exchange( final var result = restTemplate.exchange(
@ -45,7 +65,7 @@ class WebSecurityConfigIntegrationTest {
); );
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody()).startsWith("pong"); assertThat(result.getBody()).startsWith("pong test-user");
} }
@Test @Test

View File

@ -1,7 +1,6 @@
package net.hostsharing.hsadminng.test; package net.hostsharing.hsadminng.test;
import net.hostsharing.hsadminng.config.Authenticator; import net.hostsharing.hsadminng.config.Authenticator;
import net.hostsharing.hsadminng.config.CasAuthenticator;
import org.springframework.boot.test.context.TestConfiguration; import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;

View File

@ -2,7 +2,6 @@ package net.hostsharing.hsadminng.test;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import net.hostsharing.hsadminng.config.Authenticator; import net.hostsharing.hsadminng.config.Authenticator;
import net.hostsharing.hsadminng.config.CasAuthenticator;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;