Spring Security integration library with Custom GraphQL Directive @auth
Inspired by Authentication with Custom Directives and Spring Method Security
repositories {
maven("https://github.com/wickedev/graphql-jetpack/raw/deploy/maven-repo")
}
dependencies {
implementation("io.github.wickedev:graphql-jetpack-starter:0.5.6")
}
@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)")
}