From 10ecc4e1ee469ec61401646f096f325fd0623146 Mon Sep 17 00:00:00 2001
From: Andreas Svanberg <andreass@dsv.su.se>
Date: Thu, 13 Jun 2024 16:08:59 +0200
Subject: [PATCH] Switch authentication scheme to OAuth 2

This enables the same authentication mechanism for local development as for running in production. Easily switch principals with the included authorization server docker container.
---
 docker-compose.yml                            | 21 +++++++++++++++++++
 pom.xml                                       |  4 ++++
 .../java/se/su/dsv/whisperapi/HelloWorld.java |  6 ++++--
 .../dsv/whisperapi/WhisperApiApplication.java |  3 +--
 src/main/resources/application.properties     | 10 ++++++++-
 5 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/docker-compose.yml b/docker-compose.yml
index 7d7466f..1121819 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -7,12 +7,18 @@ services:
       - DBHOST=jdbc:mariadb://whisper-api-db:3306/whisper_api
       - DBUSER=root
       - DBPASS=mariadb
+      - OAUTH2_CLIENT_ID=whisper-frontend
+      - OAUTH2_CLIENT_SECRET=s3cr3t
+      - OAUTH2_AUTH_URI=http://localhost:59751/authorize
+      - OAUTH2_TOKEN_URI=http://whisper-api-oauth2:8080/exchange
+      - OAUTH2_USER_INFO_URI=http://whisper-api-oauth2:8080/verify
     networks:
       - whisper-network
     ports:
       - '8080:8080'
     depends_on:
       - whisper-api-db
+      - whisper-api-oauth2
 
   whisper-api-db:
     container_name: whisper-api-db
@@ -29,6 +35,21 @@ services:
     volumes:
       - whisper-api-db:/var/lib/mysql
 
+  whisper-api-oauth2:
+    container_name: whisper-api-oauth2
+    build:
+      context: https://github.com/dsv-su/toker.git
+      dockerfile: embedded.Dockerfile
+    restart: on-failure
+    networks:
+      - whisper-network
+    ports:
+      - '59751:8080'
+    environment:
+      CLIENT_ID: whisper-frontend
+      CLIENT_SECRET: s3cr3t
+      CLIENT_REDIRECT_URI: http://localhost:8080/login/oauth2/code/su
+
 volumes:
   whisper-api-db:
 
diff --git a/pom.xml b/pom.xml
index 0660132..6f429a9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,6 +30,10 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-oauth2-client</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.flywaydb</groupId>
             <artifactId>flyway-core</artifactId>
diff --git a/src/main/java/se/su/dsv/whisperapi/HelloWorld.java b/src/main/java/se/su/dsv/whisperapi/HelloWorld.java
index 5a4d5c1..14c672c 100644
--- a/src/main/java/se/su/dsv/whisperapi/HelloWorld.java
+++ b/src/main/java/se/su/dsv/whisperapi/HelloWorld.java
@@ -3,10 +3,12 @@ package se.su.dsv.whisperapi;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.security.Principal;
+
 @RestController
 public class HelloWorld {
     @GetMapping("/")
-    public String helloWorld() {
-        return "Hello Andreas!";
+    public String helloWorld(Principal principal) {
+        return "Hello Andreas!" + (principal != null ? principal.getName() : "anon");
     }
 }
diff --git a/src/main/java/se/su/dsv/whisperapi/WhisperApiApplication.java b/src/main/java/se/su/dsv/whisperapi/WhisperApiApplication.java
index 81c06f8..0e652dd 100644
--- a/src/main/java/se/su/dsv/whisperapi/WhisperApiApplication.java
+++ b/src/main/java/se/su/dsv/whisperapi/WhisperApiApplication.java
@@ -18,8 +18,7 @@ public class WhisperApiApplication {
     public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
         http.authorizeHttpRequests(
                 authorize -> authorize.anyRequest().authenticated())
-                .jee(Customizer.withDefaults())
-                .httpBasic(Customizer.withDefaults());
+                .oauth2Login(Customizer.withDefaults());
         return http.build();
     }
 }
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index a0ae320..8f550ea 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -3,4 +3,12 @@ spring.datasource.url=${DBHOST}
 spring.datasource.username=${DBUSER}
 spring.datasource.password=${DBPASS}
 spring.security.user.name=admin
-spring.security.user.password=admin
\ No newline at end of file
+spring.security.user.password=admin
+spring.security.oauth2.client.registration.su.client-id=${OAUTH2_CLIENT_ID}
+spring.security.oauth2.client.registration.su.client-secret=${OAUTH2_CLIENT_SECRET}
+spring.security.oauth2.client.registration.su.authorization-grant-type=authorization_code
+spring.security.oauth2.client.registration.su.redirect-uri={baseUrl}/login/oauth2/code/su
+spring.security.oauth2.client.provider.su.authorization-uri=${OAUTH2_AUTH_URI}
+spring.security.oauth2.client.provider.su.token-uri=${OAUTH2_TOKEN_URI}
+spring.security.oauth2.client.provider.su.user-info-uri=${OAUTH2_USER_INFO_URI}
+spring.security.oauth2.client.provider.su.user-name-attribute=sub