Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom auth on route #34

Closed
mintu19 opened this issue Apr 11, 2020 · 5 comments
Closed

Custom auth on route #34

mintu19 opened this issue Apr 11, 2020 · 5 comments

Comments

@mintu19
Copy link

mintu19 commented Apr 11, 2020

I am trying to do custom token based authentication on whole route but using ktor authentication is not working. How to add authentication method for openapi?

fun Routing.userRoute() {
    apiRouting {
        authenticate {
            route("users", Tags.USER) {
                route("agent").get<Unit, UserAgentResponse>(
                    info("Get Agent", "Get agent used to get images from server"),
                    example = UserAgentResponse("qwerty")
                ) {
                    respond(UserAgentResponse(Helper.userAgent))
                }
            }
        }
    }
}
@Wicpar
Copy link
Collaborator

Wicpar commented Apr 11, 2020

It is not possible to get Ktor information on the authentication, you would need to implement the interface yourself to provide the information, here are previous related issues for details:
OAuth: #30
JWT: #8

@mintu19
Copy link
Author

mintu19 commented Apr 11, 2020

I have checked above issues but not able to understand how to implement it for my custom auth provider (it is like digest) and how to use it with routes inside apiRouting. That is to use it with all routes individually or can use it like above?

@Wicpar
Copy link
Collaborator

Wicpar commented Apr 12, 2020

To use it like you want up there you would:

  1. Implement the auth handler:
private lass CustomAuthProvider(scopes: List<T>) : AuthProvider<A> {
        override suspend fun getAuth(pipeline: PipelineContext<Unit, ApplicationCall>): A {
             // return the object that represents an authenticated user, like the ktor authentication()
        }

        // use the ktor authentication on the route, the throw is optional but recommended if you want to handle errors properly
        override fun apply(route: NormalOpenAPIRoute): OpenAPIAuthenticatedRoute<A> =
            OpenAPIAuthenticatedRoute(route.ktorRoute.authenticate(authName) {}, route.provider.child(), this).throws(
                APIException.apiException<BadPrincipalException>(HttpStatusCode.Unauthorized)
            )
        // tell OpenAPI how to generate the security definition you implemented
        override val security: Iterable<Iterable<AuthProvider.Security<*>>> =
            listOf(listOf(AuthProvider.Security(scheme, scopes)))
    }
  1. Define a helper function to implement it on your route
inline fun<T> NormalOpenAPIRoute.auth(provider: AuthProvider<T>, crossinline route: OpenAPIAuthenticatedRoute<T>.()->Unit = {}): OpenAPIAuthenticatedRoute<T> {
    return provider.apply(this).apply {
        route()
    }
}
  1. use it
val authProvider = CustomAuthProvider() // you could also have the authProvider as an object instead

fun Routing.userRoute() {
    apiRouting {
        auth(authProvider) { // use it wherever you have a non authenticated route to create an authenticated one
            route("users", Tags.USER) {
                route("agent").get<Unit, UserAgentResponse>(
                    info("Get Agent", "Get agent used to get images from server"),
                    example = UserAgentResponse("qwerty")
                ) {
                    respond(UserAgentResponse(Helper.userAgent))
                }
            }
        }
    }
}

@mintu19
Copy link
Author

mintu19 commented Apr 15, 2020

It worked. Testing it now.

@Wicpar Wicpar closed this as completed Apr 18, 2020
@AndreyZS
Copy link

AndreyZS commented Mar 9, 2021

Good afternoon, you can please a more detailed example of implementation, unfortunately I do not understand how to implement "getAuth" and "security" for jwt ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants