feat(fullstack): Add JWT validation
This commit is contained in:
@@ -8,7 +8,10 @@ info:
|
||||
email: denis.lugowski@gmail.com
|
||||
|
||||
servers:
|
||||
- url: /
|
||||
- url: http://localhost:8080
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
|
||||
paths:
|
||||
/application-forms:
|
||||
@@ -592,6 +595,12 @@ paths:
|
||||
$ref: "https://api.swaggerhub.com/domains/smartbear-public/ProblemDetails/1.0.0#/components/responses/ServiceUnavailable"
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
|
||||
schemas:
|
||||
####### UserDto #######
|
||||
UserDto:
|
||||
|
||||
@@ -24,9 +24,12 @@ dependencies {
|
||||
implementation 'com.fasterxml.jackson.module:jackson-module-kotlin'
|
||||
implementation 'org.jetbrains.kotlin:kotlin-reflect'
|
||||
implementation 'org.liquibase:liquibase-core'
|
||||
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.4'
|
||||
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.6'
|
||||
implementation 'org.springdoc:springdoc-openapi-ui:1.8.0'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||
// https://docs.spring.io/spring-security/reference/servlet/oauth2/index.html#oauth2-resource-server-access-token-jwt
|
||||
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
runtimeOnly 'com.h2database:h2'
|
||||
testImplementation 'org.jetbrains.kotlin:kotlin-test-junit5'
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.betriebsratkanzlei.legalconsenthub.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.config.annotation.web.configuration.EnableWebSecurity
|
||||
import org.springframework.security.config.annotation.web.invoke
|
||||
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder
|
||||
import org.springframework.security.web.SecurityFilterChain
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
class SecurityConfig {
|
||||
|
||||
@Bean
|
||||
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
|
||||
http {
|
||||
csrf { disable() }
|
||||
authorizeHttpRequests {
|
||||
authorize("/swagger-ui/**", permitAll)
|
||||
authorize("/v3/**", permitAll)
|
||||
authorize(anyRequest, authenticated)
|
||||
}
|
||||
oauth2ResourceServer {
|
||||
jwt { }
|
||||
}
|
||||
}
|
||||
|
||||
return http.build()
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun jwtDecoder(): JwtDecoder {
|
||||
return NimbusJwtDecoder.withJwkSetUri("http://192.168.178.105:3001/api/auth/jwks")
|
||||
.jwsAlgorithm(SignatureAlgorithm.ES512).build()
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,14 @@ spring:
|
||||
order_inserts: true
|
||||
enable_lazy_load_no_trans: true
|
||||
|
||||
# security:
|
||||
# oauth2:
|
||||
# resourceserver:
|
||||
# jwt:
|
||||
# issuer-uri: http://192.168.178.105:3001
|
||||
# jwk-set-uri: http://192.168.178.105:3001/api/auth/jwks
|
||||
# jws-algorithms: ES512
|
||||
|
||||
liquibase:
|
||||
enabled: true
|
||||
drop-first: false
|
||||
@@ -31,3 +39,10 @@ spring:
|
||||
sql:
|
||||
init:
|
||||
platform: h2
|
||||
|
||||
logging:
|
||||
level:
|
||||
org:
|
||||
springframework:
|
||||
security: TRACE
|
||||
oauth2: TRACE
|
||||
|
||||
@@ -12,7 +12,7 @@ export function useApplicationFormApi() {
|
||||
)
|
||||
|
||||
const applicationFormApiClient = new ApplicationFormApi(
|
||||
new Configuration({ basePath, headers: { Authorization: jwt.value ?? '' } })
|
||||
new Configuration({ basePath, headers: { Authorization: jwt.value ? `Bearer ${jwt.value}` : '' } })
|
||||
)
|
||||
|
||||
async function createApplicationForm(
|
||||
|
||||
@@ -5,12 +5,15 @@ import { cleanDoubleSlashes, withoutTrailingSlash } from 'ufo'
|
||||
export function useApplicationFormTemplateApi() {
|
||||
const appBaseUrl = useRuntimeConfig().app.baseURL
|
||||
const { serverApiBaseUrl, serverApiBasePath, clientProxyBasePath } = useRuntimeConfig().public
|
||||
const { jwt } = useAuth()
|
||||
|
||||
const basePath = withoutTrailingSlash(
|
||||
cleanDoubleSlashes(import.meta.client ? appBaseUrl + clientProxyBasePath : serverApiBaseUrl + serverApiBasePath)
|
||||
)
|
||||
|
||||
const applicationFormApiClient = new ApplicationFormTemplateApi(new Configuration({ basePath }))
|
||||
const applicationFormApiClient = new ApplicationFormTemplateApi(
|
||||
new Configuration({ basePath, headers: { Authorization: jwt.value ? `Bearer ${jwt.value}` : '' } })
|
||||
)
|
||||
|
||||
async function createApplicationFormTemplate(
|
||||
createApplicationFormDto: CreateApplicationFormDto
|
||||
|
||||
@@ -7,7 +7,17 @@ export const auth = betterAuth({
|
||||
database: new Database('./sqlite.db'),
|
||||
emailAndPassword: { enabled: true, autoSignIn: false },
|
||||
plugins: [
|
||||
jwt(),
|
||||
jwt({
|
||||
jwt: {
|
||||
issuer: 'http://192.168.178.105:3001'
|
||||
},
|
||||
jwks: {
|
||||
keyPairConfig: {
|
||||
// Supported by NimbusJwtDecoder
|
||||
alg: 'ES512'
|
||||
}
|
||||
}
|
||||
}),
|
||||
organization({
|
||||
async sendInvitationEmail(data) {
|
||||
console.log('Sending invitation email', data)
|
||||
|
||||
Reference in New Issue
Block a user