How to enable spring security kotlin DSL? - spring-boot

How can we enable support for the spring security kotlin DSL?
As you can see from the Screenshot of the IDE (IntelliJ), the DSL is not available:
This is the full SecurityConfig.kt file:
package com.example.backend.core
import org.springframework.context.annotation.Bean
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity
import org.springframework.security.config.web.server.ServerHttpSecurity
import org.springframework.security.web.server.SecurityWebFilterChain
#EnableWebFluxSecurity
class SecurityConfig {
#Bean
fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain? {
return http {
csrf { disable() }
formLogin { disable() }
httpBasic { disable() }
// ...
}
}
}
This is our build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
val springBootVersion = "2.4.2"
plugins {
id("org.springframework.boot") version "2.4.2"
id("io.spring.dependency-management") version "1.0.11.RELEASE"
kotlin("jvm") version "1.4.21"
kotlin("plugin.spring") version "1.4.21"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11
configurations {
compileOnly {
extendsFrom(configurations.annotationProcessor.get())
}
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server")
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
implementation("org.flywaydb:flyway-core")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
developmentOnly("org.springframework.boot:spring-boot-devtools")
runtimeOnly("io.micrometer:micrometer-registry-prometheus")
runtimeOnly("org.postgresql:postgresql")
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("io.projectreactor:reactor-test")
testImplementation("org.springframework.security:spring-security-test")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "11"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
And this is the intellij version:
IntelliJ IDEA 2020.3 (Community Edition)
Build #IC-203.5981.155, built on November 30, 2020
Runtime version: 11.0.9+11-b1145.21 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
Linux 5.4.0-64-generic
GC: ParNew, ConcurrentMarkSweep
Memory: 1979M
Cores: 12
Registry: compiler.automake.allow.when.app.running=true
Non-Bundled Plugins: Key Promoter X, Dart, io.flutter, Lombook Plugin, org.jetbrains.kotlin
Current Desktop: X-Cinnamon
Do we miss some dependency? Does it require any specific intellij setup?

You need to manually import the ServerHttpSecurity invoke.
import org.springframework.security.config.web.server.invoke
Because of this Kotlin issue in 1.4, the IDE does not suggest it to you as it should.
This is scheduled to be fixed in Kotlin 1.4.30.

I noticed your question was regarding WebFlux, but just complementing #Eleftheria's answer.
For WebMvc folks you should import:
import org.springframework.security.config.web.servlet.invoke
(servlet vs server)

What worked for me was to explicitly call the .invoke method on the HttpSecurity object:
http.invoke {
csrf { disable }
}
which will force my IDE (I'm using IntelliJ) to import the .invoke.

This DSL is built in starting since Spring Security 5.3 version. For example the org.springframework.security:spring-security-config:5.3.4.RELEASE library has it: org.springframework.security.config.web.servlet.HttpSecurityDsl#csrf And for example the
compile group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: '2.3.3.RELEASE'
library will contain it.

Related

Unresolved symbol:mainClassName

I have a SpringBoot project with the following build.gradle:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.7.0"
id("io.spring.dependency-management") version "1.0.9.RELEASE"
kotlin("jvm") version "1.7.0"
kotlin("plugin.spring") version "1.7.0"
kotlin("plugin.jpa") version "1.6.21"
id("org.flywaydb.flyway") version "6.4.4"
}
group = "com.planes"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_1_8
repositories {
mavenCentral()
}
dependencies {
implementation("org.apache.tomcat.embed:tomcat-embed-jasper")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("io.jsonwebtoken:jjwt:0.9.0")
implementation("org.postgresql:postgresql")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core")
testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
}
testImplementation("org.springframework.security:spring-security-test")
}
tasks.withType<Test> {
useJUnitPlatform()
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "1.8"
}
}
springBoot {
mainClassName = "com.planes.planesserver.DemoApplication"
}
When I run the Gradle Wrapper Task I get the following error: "Unresolved reference: mainClassName"
This happens after I updated SpringBoot from Version 2.2 to 2.7 and gradle from version 5 to version 6.9.3
In the previous configuration the project could compile just fine. Are there any adjustments I need to still make for this new configuration ?
Can anyone please give a suggestion ?
In Springboot 2.4 they changed the name and type of the main classname property, see in Springboot 2.4 Release notes:
You need to update your build script as follows :
springBoot {
// before springboot 2.4
// mainClassName = "com.planes.planesserver.DemoApplication"
// since springboot 2.4 :
mainClass.set( "com.planes.planesserver.DemoApplication")
}

Migrating Spring Boot Applications to the Latest Java Version (Java 15)

I have a spring boot project set up to use Java 8 and Kotlin. I want to migrate the project to Java 15, but unfortunately I haven't found any documentation useful for that purpose.
So far i was able to upgrade my Spring boot version from 2.3.3.RELEASE to version 2.4.0 and reference the project to use Java 14 in jvmTarget based on a project example created using the spring initializr.
However, I didn't the find a way to upgrade to Java 15. Any ideas would be very appreciate it.
This is how my build.gradle looks like:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.lang.System.getenv
buildscript {
repositories {
maven {
url = uri("https://plugins.gradle.org/m2/")
}
}
dependencies {
classpath("org.jmailen.gradle:kotlinter-gradle:3.0.2")
}
}
plugins {
id("org.springframework.boot") version "2.4.0"
id("io.spring.dependency-management") version "1.0.10.RELEASE"
kotlin("jvm") version "1.4.0"
kotlin("plugin.spring") version "1.4.0"
id ("org.owasp.dependencycheck") version "5.3.2"
id ("com.github.spotbugs") version "4.5.0"
id ("org.jmailen.kotlinter") version "3.0.2"
`jacoco`
}
tasks.named<org.springframework.boot.gradle.tasks.run.BootRun>.
("bootRun") {
args("--spring.profiles.active=local")
}
jacoco {
toolVersion = "0.8.6"
}
group = "au.project"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_1_8
repositories {
mavenCentral()
maven {
url = uri("https://...")
credentials {
username = getenv("ARTIFACTORY_USER")
password = getenv("ARTIFACTORY_PASSWORD")
}
}
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-
webflux")
implementation("com.fasterxml.jackson.module:jackson-module-
kotlin")
implementation("io.github.microutils:kotlin-logging:1.8.3")
implementation("io.projectreactor.kotlin:reactor-kotlin-
extensions")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
implementation("org.owasp:dependency-check-gradle:5.3.2")
implementation("org.springdoc:springdoc-openapi-kotlin:1.4.8")
implementation("org.springdoc:springdoc-openapi-webflux-ui:1.4.8")
developmentOnly("org.springframework.boot:spring-boot-devtools")
testImplementation("org.springframework.boot:spring-boot-starter-
test") {
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
}
testImplementation("io.projectreactor:reactor-test")
testImplementation("com.github.tomakehurst:wiremock-jre8:2.27.2")
testImplementation("com.openpojo:openpojo:0.8.6")
}
tasks.withType<Test> {
useJUnitPlatform()
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "14"
}
}
....
Note: Chaning the jvmTarget = 15 for the kotlinOptions property within the build.gradle, I am getting the following exception: "Unknown JVM target version: 15 Supported version: 1.6, 1.8, 9,10,11,12,12,14. Does it means Kotlin does not support Java 15?
JDK 15 requires Gradle 6.7.x, please update Gradle first, if you haven't done so, yet.
I recommend you use the new toolchain feature of Gradle. It will download the required JDK to build your code, if it cannot detect it on the host system, to guarantee that the build is executed with the required JDK version. This also simplifies the right build in different environments with a mixed team.
java {
toolchain {
// automatically download a jdk for the build if not available
languageVersion.set(JavaLanguageVersion.of(11))
}
}
This does not work together with java.sourceCompatibility and java.targetCompatibility, you would need to remove these configurations.
First of all, you need to upgrade to latest version of Gradle, i.e (6.7.x) to support JDK 15.
Add or update the following lines in build.gradle :
java.sourceCompatibility = JavaVersion.VERSION_15
java.targetCompatibility = JavaVersion.VERSION_15

How to import amazon s3 for spring boot using gradle kotlin dsl

I have tried to import s3 in my spring boot project following the instructions on the official docs but the dependencies aren't being resolved. https://docs.aws.amazon.com/sdk-for-java/v2/developer-guide/setup-project-gradle.html
I updated the software.amazon.awssdk:bom from the documentation to the latest 2.7.16 hoping this will fix it.
this is my build.gradle.kts file
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("plugin.jpa") version "1.3.31"
id("org.springframework.boot") version "2.1.5.RELEASE"
id("io.spring.dependency-management") version "1.0.7.RELEASE"
kotlin("jvm") version "1.3.31"
kotlin("plugin.spring") version "1.3.31"
kotlin("plugin.noarg") version "1.3.31"
}
allOpen {
annotation("javax.persistence.Entity")
annotation("javax.persistence.MappedSuperclass")
annotation("javax.persistence.Embeddable")
}
noArg {
annotation("javax.persistence.Entity")
}
group = "com.leaveentry"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_1_8
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.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("com.google.api-client:google-api-client:1.25.0")
implementation("io.jsonwebtoken:jjwt-api:0.10.5")
implementation(platform("software.amazon.awssdk:bom:2.7.16"))
implementation("software.amazon.awssdk:s3")
runtimeOnly("com.h2database:h2")
runtimeOnly("mysql:mysql-connector-java")
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.10.5")
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.10.5")
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.security:spring-security-test")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "1.8"
}
}
When I try to import s3 related classes, they are not resolved.
import com.amazonaws.auth.AWSStaticCredentialsProvider
import com.amazonaws.auth.BasicAWSCredentials
import com.amazonaws.regions.Regions
import com.amazonaws.services.s3.AmazonS3ClientBuilder
import com.amazonaws.services.s3.model.CannedAccessControlList
import com.amazonaws.services.s3.model.PutObjectRequest
I've had similar issues and although I didn't manage to make that specific version of amazon bom work, I found a workaround.
Add to your build.gradle.kts the following lines:
dependencyManagement {
imports {
mavenBom("com.amazonaws:aws-java-sdk-bom:1.11.228")
}
}
and the following implementation inside the dependencies block:
implementation("software.amazon.awssdk:s3:2.10.1")
Note: Alternatively, you can add the following if you want to include all the services at once:
implementation("software.amazon.awssdk:aws-sdk-java:2.10.1")

Kotlin: Cannot inline bytecode built with JVM target 1.8 into byte code with JVM target 1.6

I have an issue when trying to add a few dependencies to my kotlin spring project. I used the spring boot initializer to get a basic project running.
My problem: If I uncomment jackson or either Koin dependency then my build fails with the mentioned in the titile
Here is the build.gradle.kts file :
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("plugin.jpa") version "1.3.31"
id("org.springframework.boot") version "2.2.0.M4"
id("io.spring.dependency-management") version "1.0.7.RELEASE"
kotlin("jvm") version "1.3.31"
kotlin("plugin.spring") version "1.3.31"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_1_8
val developmentOnly by configurations.creating
configurations {
runtimeClasspath {
extendsFrom(developmentOnly)
}
}
repositories {
mavenCentral()
maven { url = uri("https://repo.spring.io/snapshot") }
maven { url = uri("https://repo.spring.io/milestone") }
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
developmentOnly("org.springframework.boot:spring-boot-devtools")
runtimeOnly("com.h2database:h2")
testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
exclude(group = "junit", module = "junit")
}
// jackson
//implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.9.+")
// Koin
//implementation("org.koin:koin-core:2.0.1")
// Koin Test
//implementation("org.koin:koin-test:2.0.1")
}
tasks.withType<Test> {
useJUnitPlatform()
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "1.8"
}
}
I Have already tried all the solutions from this previous question someone else asked: Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6
I already had the KotlinCompile jvmTarget option in there and it has been set in my build settings as well. Any help is appreciated thanks!
A lot of the answers to this are android specific - using kotlin to write a spring boot app isn't that well documented or supported but still awesome. This setting in intelij cleared this error for me - hope it helps someone, my kotlin compiler had a target set to 1.6:

Spring complains #EnableWebMvc when I haven't used that annotation nor any dependency related to MVC

I am working on a reactive spring boot api server. I first wanted to use MVC pattern, but I thought reactor would be a good idea.
So I have deleted all spring dependencies on MVC (I believe).
But spring keeps complaining that I can't use #EnableWebMvc along #EnableWebFlux.
Following is my error log
Caused by: java.lang.IllegalStateException: The Java/XML config for Spring MVC and Spring WebFlux cannot both be enabled, e.g. via #EnableWebMvc and #EnableWebFlux, in the same application.
What possibly could be the problem? I sure did updated my dependencies.
And following is my build.gradle.kts file
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
buildscript {
repositories {
mavenCentral()
}
dependencies {
"classpath"(group = "gradle.plugin.com.palantir.gradle.docker", name = "gradle-docker")
}
}
plugins {
kotlin("plugin.jpa") version "1.3.40"
id("org.springframework.boot") version "2.1.6.RELEASE"
id("io.spring.dependency-management") version "1.0.7.RELEASE"
id("com.palantir.docker") version "0.22.1"
kotlin("jvm") version "1.3.40"
kotlin("plugin.spring") version "1.3.40"
}
group = "com.mycompany"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_1_8
val developmentOnly by configurations.creating
configurations {
runtimeClasspath {
extendsFrom(developmentOnly)
}
}
repositories {
mavenCentral()
maven(url = "https://repo.spring.io/snapshot")
maven(url = "https://repo.spring.io/milestone")
}
extra["springCloudVersion"] = "Greenwich.SR1"
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-batch")
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
//reactor
implementation("io.projectreactor:reactor-core")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("org.springframework.data:spring-data-jdbc:1.0.0.r2dbc-SNAPSHOT")
implementation("org.springframework.data:spring-data-r2dbc:1.0.0.M1")
implementation("io.r2dbc:r2dbc-spi:1.0.0.M5")
implementation("io.r2dbc:r2dbc-postgresql:1.0.0.M6")
developmentOnly("org.springframework.boot:spring-boot-devtools")
runtimeOnly("org.postgresql:postgresql")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("io.projectreactor:reactor-test")
testImplementation("org.springframework.batch:spring-batch-test")
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
exclude(group = "junit", module = "junit")
}
}
dependencyManagement {
imports {
mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}")
mavenBom("io.projectreactor:reactor-bom:Bismuth-RELEASE")
}
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "1.8"
}
}
task<Copy>("unpack") {
dependsOn(tasks.getByName("bootJar"))
from(zipTree(tasks.getByName("bootJar").outputs.files.singleFile))
into("build/dependency")
}
I figured it out by deleting each dependencies I have.
The problem was
implementation("org.springframework.boot:spring-boot-starter-web")
After deleting this, It worked. Maybe above dependency has it's own dependencies on WebMvc but I'm not sure.

Resources