Skip to content

Latest commit

 

History

History

graphql-kotlin-spring-security

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

GraphQL Kotlin Spring Security

Spring Security integration library with Custom GraphQL Directive @auth

Inspired by Authentication with Custom Directives and Spring Method Security

Getting Started

Gradle

repositories {
    maven("https://github.com/wickedev/graphql-jetpack/raw/deploy/maven-repo")
}

dependencies {
    implementation("io.github.wickedev:graphql-jetpack-starter:0.5.6")
}

Example

@Configuration
class SecurityConfiguration {
    @Bean
    fun configure(http: ServerHttpSecurity): SecurityWebFilterChain {
        return http {
            csrf { disable() }
            httpBasic { disable() }
            formLogin { disable() }
            logout { disable() }
            authorizeExchange {
                authorize("/graphql", permitAll)
            }
            addFilterAt(MyAuthenticationWebFilter(authenticationManager), SecurityWebFiltersOrder.AUTHENTICATION)
        }
    }

    @Bean
    fun roleHierarchy(): RoleHierarchy = RoleHierarchyImpl().apply { // Optional
        setHierarchy("ROLE_ADMIN > ROLE_MANAGER > ROLE_USER")
    }
}

@Component
class Resource {
    fun ownershipFor(userId: ID, authentication: Authentication): Boolean {
        return userId == authentication.id  
    }
}

@Component
class SampleQuery : Query {

    fun public(): Int = 1

    @Auth
    fun protected(): Int = 1

    @Auth("hasRole('USER')")
    fun protectedWithRole(): Int = 1

    @Auth("#param == 1")
    fun protectedWithParam(param: Int): Int = param

    @Auth("@resource.ownershipFor(#userId, #authentication)")
    fun userSensitiveData(userId: ID, @GraphQLIgnore authentication: Authentication): SensitiveData = SensitiveData(userId)
}
directive @auth(require: String!) on FIELD | FIELD_DEFINITION

type Query {
    
    public: Int!
    
    protected: Int! @auth(require : "isAuthenticated")
    
    protectedWithRole: Int! @auth(require : "hasRole('USER')")
    
    hiddenPost(postId: Int!): Post! @auth(require : "#param == 1")
    
    userSensitiveData(userId: ID!): SensitiveData! @auth(require : "@resource.ownershipFor(#userId, #authentication)")  
}