ECE366 - Lesson 13

Authentication on the Cloud

Instructor: Professor Hong

Early Final Presentations

## More Hosting on the Cloud
## webservice/Webconfig.java ```java package ece366.rpsjdbc.webservice; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // Apply CORS to all endpoints .allowedOrigins("http://moosetracks.eastus.azurecontainer.io") // Allow requests from your frontend .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // Allow specific HTTP methods .allowedHeaders("*") // Allow all headers, including Authorization .allowCredentials(true); // Allow cookies or Authorization headers } } ```
## webservice/WebserviceController.java ``` package ece366.rpsjdbc.webservice; import ece366.rpsjdbc.DatabaseConnectionManager; import ece366.rpsjdbc.Player; import ece366.rpsjdbc.PlayerDAO; import org.springframework.web.bind.annotation.*; import java.sql.Connection; import java.sql.SQLException; import java.util.List; import java.util.Map; @RestController @RequestMapping("/api") public class WebserviceController { private final PlayerDAO playerDAO; private final boolean isTestMode; // Constructor for dependency injection (used in tests) public WebserviceController(PlayerDAO playerDAO) { this.playerDAO = playerDAO; this.isTestMode = true; // Indicates that this is a test instance } // Default constructor (used in production) public WebserviceController() { this.isTestMode = false; this.playerDAO = null; // Will be initialized dynamically in production } @GetMapping("/testPlayer") public String getTestPlayer() { return "TEST PLAYER"; } @GetMapping("/player/{id}") public Player getPlayerById(@PathVariable Long id) { System.out.println("getPlayerById: " + id); try { // Use injected PlayerDAO in test mode, otherwise create it dynamically PlayerDAO dao = isTestMode ? playerDAO : createPlayerDAO(); Player player = dao.findById(id); System.out.println(player.toString()); return player; } catch (Exception e) { e.printStackTrace(); } return null; } // Factory method to create PlayerDAO in production private PlayerDAO createPlayerDAO() throws SQLException { DatabaseConnectionManager dcm = new DatabaseConnectionManager("localhost", "rps", "postgres", "password"); Connection connection = dcm.getConnection(); return new PlayerDAO(connection); } } ```
## Azure Review ``` az login az acr login --name ece366acr az acr login --name ece366acr --expose-token docker compose build docker compose push az container create --resource-group ece366rg --file deploy-aci.yaml ```
## Add Back Security Dependencies in pom.xml ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ```
## resources/application.properties ``` spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://www.googleapis.com/service_accounts/v1/jwk/securetoken%40system.gserviceaccount.com ```
## config/SecurityConfig.java ``` package ece366.rpsjdbc.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; @Configuration public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .csrf(csrf -> csrf.disable()) // Disable CSRF using the new syntax .authorizeHttpRequests(authorize -> authorize .requestMatchers(org.springframework.http.HttpMethod.OPTIONS, "/**").permitAll() // Allow all OPTIONS requests .requestMatchers("/api/**").permitAll() // Allow all requests to /api/** without authentication .anyRequest().authenticated() // Require authentication for other endpoints ); return http.build(); } } ```
## ``` package ece366.rpsjdbc.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; import org.springframework.security.web.SecurityFilterChain; @Configuration public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .csrf(csrf -> csrf.disable()) // Disable CSRF for simplicity .authorizeHttpRequests(authorize -> authorize .requestMatchers(org.springframework.http.HttpMethod.OPTIONS, "/**").permitAll() // Allow all OPTIONS requests .requestMatchers("/api/testPlayer").permitAll() // Allow unauthenticated access to test endpoint .anyRequest().authenticated() // Require authentication for all other endpoints ) .oauth2ResourceServer(oauth2 -> oauth2 .jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverter())) // Use JwtConfigurer ); return http.build(); } private JwtAuthenticationConverter jwtAuthenticationConverter() { JwtAuthenticationConverter converter = new JwtAuthenticationConverter(); // Customize the converter if needed (e.g., map roles or claims) return converter; } } ```
## ``` ```
## ``` ```