Aufbau einer sicheren Spring Boot Anwendung mit Kotlin, Spring Security und Coroutines

Mehr auf Medium lesen

In diesem Tutorial erfahren Sie, wie Sie mit Kotlin eine sichere Spring Boot-Anwendung erstellen, Spring Security für die Authentifizierung integrieren, Coroutines für die asynchrone Programmierung nutzen und mit AWS-Services wie Athena und Cognito integrieren. Wir werden auch die Datenbankmigration mit Flyway und das kontinuierliche Deployment mit Jenkins behandeln.

Voraussetzungen:

  • Grundkenntnisse der Programmiersprache Kotlin.
  • Vertrautheit mit dem Spring Boot-Framework.
  • Ein AWS-Konto mit Zugriff auf die Dienste Athena und Cognito.
  • Grundlegendes Verständnis von Gradle für die Projektverwaltung.
1. Einrichten des Projekts

Lass uns zunächst das Spring Boot Projekt mit Kotlin unter Verwendung von Gradle einrichten:

Schritt 1: Erzeugen des Spring Boot Projekts

Sie können Spring Initializr verwenden, um das Projekt mit den erforderlichen Konfigurationen zu generieren. Gehen Sie zu https://start.spring.io/ und geben Sie die folgenden Details ein:

  • Projekt: Kotlin
  • Dependencies: Spring Security, AWS Athena, AWS Cognito, Spring Data JPA, H2 Database, Flyway, Gradle, und Spring Boot DevTools.

Klicken Sie auf “Generate”, um die Projekt-Zip-Datei herunterzuladen.

Schritt 2: Gradle einrichten

Entpacken Sie das heruntergeladene Projekt, und im Root-Ordner finden Sie eine build.gradle-Datei. Ändern Sie diese so, dass sie die notwendigen Konfigurationen für die Elastic Beanstalk-Bundle-Generierung und die Jenkins-Integration enthält.

plugins {
id 'org.springframework.boot' version '2.5.4'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'org.jetbrains.kotlin.jvm' version '1.5.21'
id 'org.jetbrains.kotlin.plugin.spring' version '1.5.21'
id 'org.jetbrains.kotlin.plugin.jpa' version '1.5.21'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java.sourceCompatibility = JavaVersion.VERSION_11
kotlin {
experimental {
coroutines 'enable'
}
}
repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'com.amazonaws:aws-java-sdk-athena'
implementation 'com.amazonaws:aws-java-sdk-cognitoidp'
implementation 'com.amazonaws:aws-java-sdk-core'
implementation 'com.amazonaws:aws-java-sdk-elasticbeanstalk'
implementation 'com.h2database:h2'
implementation 'org.flywaydb:flyway-core'

developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'org.postgresql:postgresql'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

springBoot {
buildInfo {
properties {
additional = ['build.version': version]
}
}
}

tasks.named('test') {
useJUnitPlatform()
}

Schritt 3: Einrichten von Spring Security und AWS Cognito

Erstellen Sie eine Konfigurationsklasse für Spring Security mit AWS Cognito-Integration:

@Configuration
@EnableWebSecurity
class SecurityConfig : WebSecurityConfigurerAdapter() {
override fun configure(http: HttpSecurity) {
http.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.antMatchers("/api/**").authenticated()
.and()
.oauth2Login()
}
}

Schritt 4: Authentifizierungsanbieter anpassen

Konfigurieren Sie einen benutzerdefinierten Authentifizierungsanbieter für die Integration mit AWS Cognito:

@Component
class CustomAuthenticationProvider : AuthenticationProvider {

override fun authenticate(authentication: Authentication): Authentication {
// Implement authentication logic with AWS Cognito
}

override fun supports(authentication: Class<*>): Boolean {
return UsernamePasswordAuthenticationToken::class.java.isAssignableFrom(authentication)
}
}

Schritt 5: UserDetailsService erstellen

Implementieren Sie einen benutzerdefinierten UserDetailsService, um Benutzerdetails aus AWS Cognito zu laden:

@Service
class CustomUserDetailsService : UserDetailsService {
override fun loadUserByUsername(username: String): UserDetails {
// Load user details from AWS Cognito
}
}

Schritt 6: Datenbankkonfiguration einrichten

Erstellen Sie eine Konfigurationsklasse für die verschiedenen Profile (local, dev, prod):

@Configuration
class DatabaseConfig {
@Bean
@Profile("local")
fun dataSource(): DataSource {
return EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.build()
}

@Bean
@Profile("dev", "prod")
fun dataSourceDevProd(): DataSource {
val dataSource = DriverManagerDataSource()
dataSource.setDriverClassName("YOUR_DATABASE_DRIVER")
dataSource.url = "YOUR_DATABASE_URL"
dataSource.username = "YOUR_DATABASE_USERNAME"
dataSource.password = "YOUR_DATABASE_PASSWORD"
return dataSource
}
}

Schritt 7: Flyway-Migration einrichten

Erstellen Sie ein Migrationsskript unter src/main/resources/db/migration für Flyway, um Änderungen am Datenbankschema zu verwalten.

Schritt 8: Erstellen einer Spring Boot Hauptklasse

Erstellen Sie eine Kotlin-Klasse, die als Einstiegspunkt für Ihre Spring Boot-Anwendung dient:

@SpringBootApplication
class DemoApplication

fun main(args: Array<String>) {
runApplication<DemoApplication>(*args)
}

Schritt 9: Einrichten der AWS Athena-Integration

Sie können die Integration mit AWS Athena mithilfe des AWS SDK für Java und den entsprechenden Anmeldeinformationen vornehmen. Sie können den entsprechenden Code für AWS Athena-Abfragen in Ihrer Service-Schicht oder Ihrem Controller hinzufügen.

Schritt 10: Erzeugen eines Elastic Beanstalk-Bündels in Gradle

Um ein Elastic Beanstalk-Bundle zu erstellen, müssen Sie das CLI-Tool von AWS Elastic Beanstalk verwenden, das Sie über Gradle aufrufen können. Hier ist ein Beispiel dafür, wie Sie es tun können:

task createElasticBeanstalkBundle(type: Exec) {
workingDir projectDir
commandLine 'eb', 'create'
// Add necessary AWS Elastic Beanstalk configurations here
}
tasks.named('build').dependsOn createElasticBeanstalkBundle

Dadurch wird der Befehl eb create ausgeführt, wenn Sie die Gradle-Bauaufgabe ausführen.

Schritt 11: Jenkins-Integration einrichten

Für die Jenkins-Integration müssen Sie Ihre Jenkins-Pipeline so konfigurieren, dass das Projekt unter Verwendung des generierten Gradle-Wrappers gebaut und bereitgestellt wird.

Mit diesen Schritten sollten Sie ein Spring Boot-Projekt mit Kotlin, Spring Security, AWS Cognito, AWS Athena-Integration und Flyway-Datenbankmigration haben. Darüber hinaus verfügen Sie über Konfigurationen für lokale, Dev- und Prod-Umgebungen und eine Gradle-Aufgabe für die Generierung von Elastic Beanstalk-Bundles, die zur Bereitstellung in Jenkins integriert werden können.

Mehr auf Medium lesen