diff --git a/pom.xml b/pom.xml
index bf38b3e..37dce0f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.boot
spring-boot-starter-parent
- 3.5.11
+ 4.0.6
@@ -19,7 +19,8 @@
17
- 3.1.12
+ 3.2.4
+ 4.0.6
@@ -29,12 +30,12 @@
org.springframework.boot
- spring-boot-starter-web
+ spring-boot-starter-webmvc
gg.jte
- jte-spring-boot-starter-3
+ jte-spring-boot-starter-4
${jte.version}
@@ -66,6 +67,11 @@
spring-boot-starter-tomcat
provided
+
+ org.springframework.boot
+ spring-boot-web-server
+ provided
+
@@ -73,6 +79,16 @@
spring-boot-starter-test
test
+
+ org.springframework.boot
+ spring-boot-starter-webmvc-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-jackson-test
+ test
+
org.springframework.boot
spring-boot-testcontainers
@@ -85,12 +101,12 @@
org.testcontainers
- junit-jupiter
+ testcontainers-junit-jupiter
test
org.testcontainers
- mariadb
+ testcontainers-mariadb
test
@@ -105,7 +121,7 @@
org.springframework.boot
spring-boot-configuration-processor
- 3.3.0
+ ${spring-boot.version}
@@ -171,6 +187,11 @@
org.springframework.boot
spring-boot-starter-jdbc
+
+
+ org.springframework.boot
+ spring-boot-starter-flyway
+
org.flywaydb
flyway-core
diff --git a/src/main/java/se/su/dsv/oauth2/AuthorizationServer.java b/src/main/java/se/su/dsv/oauth2/AuthorizationServer.java
index 0568506..2c9cb56 100644
--- a/src/main/java/se/su/dsv/oauth2/AuthorizationServer.java
+++ b/src/main/java/se/su/dsv/oauth2/AuthorizationServer.java
@@ -13,6 +13,7 @@ import org.springframework.security.config.Customizer;
import org.springframework.security.config.ObjectPostProcessor;
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.configurers.oauth2.server.authorization.OAuth2AuthorizationServerConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
@@ -21,7 +22,6 @@ import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationProvider;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationConsentAuthenticationProvider;
-import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;
@@ -95,7 +95,7 @@ public class AuthorizationServer extends SpringBootServletInitializer {
throws Exception
{
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
- OAuth2AuthorizationServerConfigurer.authorizationServer();
+ new OAuth2AuthorizationServerConfigurer();
String tokenEndpoint = authorizationServerSettings.getTokenEndpoint();
RequestMatcher corsEnabledMatcher = new OrRequestMatcher(
diff --git a/src/main/java/se/su/dsv/oauth2/dev/DevConfiguration.java b/src/main/java/se/su/dsv/oauth2/dev/DevConfiguration.java
index 914d585..d36aec5 100644
--- a/src/main/java/se/su/dsv/oauth2/dev/DevConfiguration.java
+++ b/src/main/java/se/su/dsv/oauth2/dev/DevConfiguration.java
@@ -1,7 +1,7 @@
package se.su.dsv.oauth2.dev;
import jakarta.servlet.http.HttpFilter;
-import org.springframework.boot.autoconfigure.security.SecurityProperties;
+import org.springframework.boot.security.autoconfigure.web.servlet.SecurityFilterProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -12,9 +12,9 @@ import se.su.dsv.oauth2.Config;
@Profile("dev")
public class DevConfiguration {
@Bean
- public FilterRegistrationBean fakeSSO(SecurityProperties securityProperties, Config config) {
+ public FilterRegistrationBean fakeSSO(SecurityFilterProperties securityProperties, Config config) {
var filter = new FilterRegistrationBean(new FakeSSOFilter(config.developerEntitlement()));
- filter.setOrder(securityProperties.getFilter().getOrder() - 1);
+ filter.setOrder(securityProperties.getOrder() - 1);
return filter;
}
}
diff --git a/src/main/java/se/su/dsv/oauth2/shibboleth/ShibbolethAuthenticationDetailsSource.java b/src/main/java/se/su/dsv/oauth2/shibboleth/ShibbolethAuthenticationDetailsSource.java
index ecae400..a55870e 100644
--- a/src/main/java/se/su/dsv/oauth2/shibboleth/ShibbolethAuthenticationDetailsSource.java
+++ b/src/main/java/se/su/dsv/oauth2/shibboleth/ShibbolethAuthenticationDetailsSource.java
@@ -3,6 +3,7 @@ package se.su.dsv.oauth2.shibboleth;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.FactorGrantedAuthority;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@@ -46,6 +47,8 @@ public class ShibbolethAuthenticationDetailsSource implements
authorities.add(entitlement);
}
}
+ // The authentication performed by Shibboleth is password based.
+ authorities.add(FactorGrantedAuthority.fromAuthority(FactorGrantedAuthority.PASSWORD_AUTHORITY));
return authorities;
}
}
diff --git a/src/main/java/se/su/dsv/oauth2/staging/CustomAuthorizationEndpointFilter.java b/src/main/java/se/su/dsv/oauth2/staging/CustomAuthorizationEndpointFilter.java
index 2089b79..e1c6d0c 100644
--- a/src/main/java/se/su/dsv/oauth2/staging/CustomAuthorizationEndpointFilter.java
+++ b/src/main/java/se/su/dsv/oauth2/staging/CustomAuthorizationEndpointFilter.java
@@ -7,7 +7,6 @@ import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpFilter;
import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletRequestWrapper;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
@@ -34,10 +33,7 @@ import se.su.dsv.oauth2.shibboleth.ShibbolethAuthenticationDetails;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Objects;
-import java.util.Set;
+import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -100,7 +96,8 @@ public class CustomAuthorizationEndpointFilter extends HttpFilter {
authenticationConverter.convert(request);
String authorizationUrl = getAuthorizationUrl(request);
- JteModel view = templates.authorize(authorizationUrl, loggedInUser.getName(), (ShibbolethAuthenticationDetails) loggedInUser.getDetails());
+ Map parameters = request.getParameterMap();
+ JteModel view = templates.authorize(authorizationUrl, parameters, loggedInUser.getName(), (ShibbolethAuthenticationDetails) loggedInUser.getDetails());
respondWithTemplate(response, view);
} else if (Objects.equals(request.getMethod(), "POST")) {
handleIncomingCustomAuthorizationRequest(request, response, loggedInUser);
@@ -119,14 +116,15 @@ public class CustomAuthorizationEndpointFilter extends HttpFilter {
principal.setDetails(buildShibbolethDetails(request));
Authentication authenticatedPrincipal = authenticationManager.authenticate(principal);
- Authentication normalCodeRequest = authenticationConverter.convert(withGetMethod(request));
+ Authentication normalCodeRequest = authenticationConverter.convert(request);
OAuth2AuthorizationCodeRequestAuthenticationToken codeRequestAuthenticationToken = (OAuth2AuthorizationCodeRequestAuthenticationToken) normalCodeRequest;
Authentication codeRequest = overridePrincipal(authenticatedPrincipal, codeRequestAuthenticationToken);
Authentication authenticatedCodeRequest = authenticationManager.authenticate(codeRequest);
if (!authenticatedCodeRequest.isAuthenticated()) {
String authorizationUrl = getAuthorizationUrl(request);
- respondWithTemplate(response, templates.authorize(authorizationUrl, loggedInUser.getName(), (ShibbolethAuthenticationDetails) authenticatedPrincipal));
+ Map parameters = request.getParameterMap();
+ respondWithTemplate(response, templates.authorize(authorizationUrl, parameters, loggedInUser.getName(), (ShibbolethAuthenticationDetails) authenticatedPrincipal));
} else {
if (authenticatedCodeRequest instanceof OAuth2AuthorizationCodeRequestAuthenticationToken authenticatedCodeRequestAuthenticationToken) {
sendAuthorizationResponse(request, response, authenticatedCodeRequestAuthenticationToken);
@@ -139,16 +137,7 @@ public class CustomAuthorizationEndpointFilter extends HttpFilter {
}
private static String getAuthorizationUrl(final HttpServletRequest request) {
- return request.getRequestURL().append('?').append(request.getQueryString()).toString();
- }
-
- private HttpServletRequest withGetMethod(final HttpServletRequest request) {
- return new HttpServletRequestWrapper(request) {
- @Override
- public String getMethod() {
- return "GET";
- }
- };
+ return request.getRequestURL().toString();
}
private Authentication overridePrincipal(
diff --git a/src/main/resources/templates/authorize.jte b/src/main/resources/templates/authorize.jte
index 3974f92..7081991 100644
--- a/src/main/resources/templates/authorize.jte
+++ b/src/main/resources/templates/authorize.jte
@@ -1,8 +1,10 @@
@import se.su.dsv.oauth2.shibboleth.Entitlement
@import se.su.dsv.oauth2.shibboleth.ShibbolethAuthenticationDetails
+@import java.util.Map
@import java.util.stream.Collectors
@param String authorizationUrl
+@param Map parameters
@param String principalName
@param ShibbolethAuthenticationDetails shibbolethDetails
@@ -15,6 +17,11 @@