diff --git a/pom.xml b/pom.xml
index d5414c64f..6e38c8388 100644
--- a/pom.xml
+++ b/pom.xml
@@ -592,7 +592,16 @@
spring-security-config
${spring.security.version}
-
+
+ org.springframework.security
+ spring-security-oauth2-client
+ ${spring.security.version}
+
+
+ org.springframework.security
+ spring-security-oauth2-jose
+ ${spring.security.version}
+
org.apache.logging.log4j
diff --git a/src/main/java/de/rwth/idsg/steve/SteveConfiguration.java b/src/main/java/de/rwth/idsg/steve/SteveConfiguration.java
index 7aeb2e911..291bd6ee0 100644
--- a/src/main/java/de/rwth/idsg/steve/SteveConfiguration.java
+++ b/src/main/java/de/rwth/idsg/steve/SteveConfiguration.java
@@ -95,6 +95,14 @@ public enum SteveConfiguration {
.passwordEncoder(encoder)
.userName(p.getString("auth.user"))
.encodedPassword(encoder.encode(p.getString("auth.password")))
+ .method(p.getOptionalString("auth.method"))
+ .oAuthAuthorizationUri(p.getOptionalString("auth.oauth2.authorization-uri"))
+ .oAuthClientId(p.getOptionalString("auth.oauth2.client-id"))
+ .oAuthClientSecret(p.getOptionalString("auth.oauth2.client-secret"))
+ .oAuthTokenUri(p.getOptionalString("auth.oauth2.token-uri"))
+ .oAuthJwkSetUri(p.getOptionalString("auth.oauth2.jwk-set-uri"))
+ .oAuthUserInfoUri(p.getOptionalString("auth.oauth2.user-info-uri"))
+ .oAuthLogoutUri(p.getOptionalString("auth.oauth2.logout-uri"))
.build();
webApi = WebApi.builder()
@@ -185,6 +193,14 @@ public static class DB {
// Credentials for Web interface access
@Builder @Getter
public static class Auth {
+ private final String method;
+ private final String oAuthClientId;
+ private final String oAuthClientSecret;
+ private final String oAuthAuthorizationUri;
+ private final String oAuthTokenUri;
+ private final String oAuthUserInfoUri;
+ private final String oAuthJwkSetUri;
+ private final String oAuthLogoutUri;
private final PasswordEncoder passwordEncoder;
private final String userName;
private final String encodedPassword;
diff --git a/src/main/java/de/rwth/idsg/steve/config/SecurityConfiguration.java b/src/main/java/de/rwth/idsg/steve/config/SecurityConfiguration.java
index 65c87d867..705a27659 100644
--- a/src/main/java/de/rwth/idsg/steve/config/SecurityConfiguration.java
+++ b/src/main/java/de/rwth/idsg/steve/config/SecurityConfiguration.java
@@ -32,6 +32,9 @@
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.DisabledException;
+import org.springframework.security.config.Customizer;
+import org.springframework.security.oauth2.client.registration.ClientRegistration;
+import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
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.WebSecurityCustomizer;
@@ -44,6 +47,10 @@
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
+import org.springframework.security.oauth2.core.AuthorizationGrantType;
+import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
+import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
@@ -53,6 +60,8 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.Objects;
import static de.rwth.idsg.steve.SteveConfiguration.CONFIG;
@@ -96,25 +105,54 @@ public WebSecurityCustomizer webSecurityCustomizer() {
CONFIG.getCxfMapping() + "/**"
);
}
+ @Bean
+ public ClientRegistrationRepository clientRegistrationRepository() {
+ if (CONFIG.getAuth().getMethod().equals("oauth2")){
+ ClientRegistration registration = ClientRegistration.withRegistrationId("sso")
+ .clientId(CONFIG.getAuth().getOAuthClientId())
+ .clientSecret(CONFIG.getAuth().getOAuthClientSecret())
+ .authorizationUri(CONFIG.getAuth().getOAuthAuthorizationUri())
+ .jwkSetUri(CONFIG.getAuth().getOAuthJwkSetUri())
+ .userInfoUri(CONFIG.getAuth().getOAuthUserInfoUri())
+ .scope("openid", "profile", "email")
+ .tokenUri(CONFIG.getAuth().getOAuthTokenUri())
+ .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
+ .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
+ .userNameAttributeName(IdTokenClaimNames.SUB)
+ .redirectUri("{baseUrl}/login/oauth2/code/sso")
+ .clientName("SSO")
+ .build();
+
+ return new InMemoryClientRegistrationRepository(registration);
+ }
+ return null;
+ }
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
final String prefix = CONFIG.getSpringManagerMapping();
- return http
- .authorizeHttpRequests(
- req -> req.antMatchers(prefix + "/**").hasRole("ADMIN")
- )
- .sessionManagement(
- req -> req.invalidSessionUrl(prefix + "/signin")
- )
- .formLogin(
- req -> req.loginPage(prefix + "/signin").permitAll()
- )
- .logout(
- req -> req.logoutUrl(prefix + "/signout")
- )
- .build();
+ if (CONFIG.getAuth().getMethod().equals("oauth2")){
+ return http.authorizeHttpRequests(req -> req.antMatchers(prefix + "/**").authenticated()).oauth2Login(Customizer.withDefaults())
+ .logout(
+ req -> req.logoutUrl(prefix + "/signout")
+ ).build();
+ } else {
+ return http
+ .authorizeHttpRequests(
+ req -> req.antMatchers(prefix + "/**").hasRole("ADMIN")
+ )
+ .sessionManagement(
+ req -> req.invalidSessionUrl(prefix + "/signin")
+ )
+ .formLogin(
+ req -> req.loginPage(prefix + "/signin").permitAll()
+ )
+ .logout(
+ req -> req.logoutUrl(prefix + "/signout")
+ )
+ .build();
+ }
}
@Bean
diff --git a/src/main/java/de/rwth/idsg/steve/web/controller/SignOutController.java b/src/main/java/de/rwth/idsg/steve/web/controller/SignOutController.java
index 24150f2d6..15fd8d6bc 100644
--- a/src/main/java/de/rwth/idsg/steve/web/controller/SignOutController.java
+++ b/src/main/java/de/rwth/idsg/steve/web/controller/SignOutController.java
@@ -28,6 +28,8 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import static de.rwth.idsg.steve.SteveConfiguration.CONFIG;
+
/**
* @author Sevket Goekay
* @since 15.08.2014
@@ -42,6 +44,9 @@ public String signOut(HttpServletRequest request, HttpServletResponse response)
.logout(request, response, null);
new CookieClearingLogoutHandler(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY)
.logout(request, response, null);
+ if (CONFIG.getAuth().getMethod().equals("oauth2")){
+ return "redirect:" + CONFIG.getAuth().getOAuthLogoutUri();
+ }
return "redirect:/manager/signin";
}
}
diff --git a/src/main/resources/config/docker/main.properties b/src/main/resources/config/docker/main.properties
index bd2387635..6196c0869 100644
--- a/src/main/resources/config/docker/main.properties
+++ b/src/main/resources/config/docker/main.properties
@@ -14,6 +14,14 @@ db.password = changeme
# Credentials for Web interface access
#
+auth.method = oauth2
+auth.oauth2.client-id = Test
+auth.oauth2.client-secret = Test
+auth.oauth2.authorization-uri = https://sso/idp/profile/oidc/authorize
+auth.oauth2.token-uri = https://sso/idp/profile/oidc/token
+auth.oauth2.jwk-set-uri = https://sso/idp/profile/oidc/keyset
+auth.oauth2.user-info-uri = https://sso/idp/profile/oidc/userinfo
+auth.oauth2.logout-uri = https://sso/idp/profile/Logout
auth.user = admin
auth.password = 1234