Is it possible to make use of existing swagger and JWT middleware in Giraffe.
Just started to look at this project and will appreciate if you can speed me up.
Thank you.
Hi, could you give me an example of swagger and JWT middleware with a normal ASP.NET Core or MVC application?
@dustinmoris This is na example of JWT middleware https://dev.to/samueleresca/developing-token-authentication-using-aspnet-core
Also, might suggest you create another set of functions:
signIn -> Helper for sign incookieClaimstokenClaimsThis would require you to add Microsoft.AspNetCore.Authentication.JwtBearer and Microsoft.AspNetCore.Authentication.Cookies as direct dependencies to Giraffe.
I was able to get default JWT middleware working for API routes.
Install JWT package (NuGet version)
dotnet add <project> package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet restore
if VS Code / Ionide, make any change to .fsproj to trigger detection of new package
Configure it
(* Program.fs *)
...
let configureApp (app : IApplicationBuilder) =
let jwtOptions =
JwtBearerOptions(
Audience = "<your api url>",
Authority = "<token service url>"
)
app.UseJwtBearerAuthentication(jwtOptions) |> ignore
// ^ this does the magic of turning a valid token into a ctx.User (ClaimsPrincipal)
// it even downloads/caches public key from token service in background
...
app.UseGiraffe apiApp
// requires: open Microsoft.Extensions.DependencyInjection
let configureServices (services : IServiceCollection) =
services.AddAuthentication() |> ignore
...
Setup HttpHandler for requiring authentication
I __think__ I found AuthorizeAttribute's version of this code here. Hard to trace because it is so far removed from the Attribute.
// forgive my non-fish implementation
let authenticated ( ctx : HttpContext ) =
let isAuthenticated =
not ( isNull ctx.User )
&& not ( isNull ctx.User.Identity )
&& ctx.User.Identities |> Seq.exists (fun x -> x.IsAuthenticated)
let result =
if isAuthenticated then
Some ctx
else
None
async.Return result
Use it in routes
let apiApp =
choose [
authenticated >=>
choose [
route "/" >=> text "Hello world, from Giraffe!"
setStatusCode 404 >=> text "Not Found"
]
setStatusCode 401
]
I got this working with Auth0 (OIDC-conformance turned on), but others should work.
Awesome work! I will try to incorporate this into a small sample app which can be checked into the repo or if you like you can try it yourself and submit a PR :)
Maybe this should be 2 separate issues? They are 2 very different requests. I would love to see Swagger support. The Swashbuckle states "You must use attribute routing for any controllers that you want represented in your Swagger document(s)" which is a problem I imagine. It would be great if we could use the Swashbuckle middleware.
@dburriss yes, these are two separate issues, the JWT one being addressed in this issue (PR pending), Swashbuckle/Swagger being addressed in #79.
In #79, assuming users are referring to "Swashbuckle like" auto-mapping api to swagger, this would be done with custom mapping functions as, like you mentioned, Swashbuckle's annotations only work on classes / methods, whereas f# & giraffe compose reusable functions (of same types) that require mapping for each route instance, not each type declaration.
As such, we can probably close this issue once JWT PR merged, and then link to #79 for the continued implementation discussion of Swagger.
Hi guys,
What about the token generation part? I haven't been able to find if this functionality is part of Asp Core or will we need to write our own method.
@catalintoma Token generation uses the same middleware as above ( You need to give the public or symmetric key to the UseJwtBearerAuthentication), but you have to include more options to generate tokens.UseJwtBearerAuthentication middleware so it can verify the token. Otherwise, you generate the token separately: See the 2nd and 3rd code blocks in this article.
https://pioneercode.com/post/authentication-in-an-asp-dot-net-core-api-part-3-json-web-token
@kspeakman Thanks, I think I've read that article before.
Just to be clear, the middleware has options to automatically create the token generation route (something like POST /token) ?
@catalintoma Looks like the middleware is only for verification actually. The token creation happens in the 2nd and 3rd code blocks of the linked article. Sorry, I do not have an F# worked example for you -- I use external auth token providers, so I only deal with token verification.
@catalintoma, @kspeakman is right, it's "just" verification middleware. Here is another example for .netcore 2.0.
let jwt = requiresAuthentication (challenge JwtBearerDefaults.AuthenticationScheme)
let webApp =
choose [
GET >=>
choose [
route "/" >=> razorHtmlView "Index" { Text = "Hello world, from Giraffe!" }
route "/protected" >=> jwt >=> text "Authorized"
]
setStatusCode 404 >=> text "Not Found" ]
let configureServices (services : IServiceCollection) =
let sp = services.BuildServiceProvider()
let env = sp.GetService<IHostingEnvironment>()
let viewsFolderPath = Path.Combine(env.ContentRootPath, "Views")
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(fun x ->
let events = JwtBearerEvents()
events.OnAuthenticationFailed <- fun context ->
context.Fail "Authentication failed"
Task.CompletedTask
x.RequireHttpsMetadata <- false
x.Authority <- "http://localhost:5050/identity"
x.Audience <- "sebastian"
x.Events <- events) |> ignore
services.AddRazorEngine viewsFolderPath |> ignore
I wanted to prepare also an example for generating JWT token, but unfortunately, not all required libraries have been ported to netstandard2 yet.
But at least you can try to use OpenIddict as far I know it's one of solution which been ported to netcoreapp2.0.
I've put some JWT generator there: JWT generator It works with .NET Core.
I've put together a sample application for JWT auth with .NET Core 2. It also demonstrates pulling authenticated data from claims and making use of that in web operations. It's available here: https://github.com/dustinmoris/Giraffe/pull/101
I've renamed the issue as the JWT support question has been sufficiently answered I believe. Thanks @torhovland @rmotyka @Sebosek @kspeakman for your help on this!
Actually I am going to close this as a duplicate and suggest to continue any Swagger support conversation in #79.
Most helpful comment
@dustinmoris This is na example of JWT middleware https://dev.to/samueleresca/developing-token-authentication-using-aspnet-core
Also, might suggest you create another set of functions:
signIn-> Helper for sign incookieClaimstokenClaimsThis would require you to add
Microsoft.AspNetCore.Authentication.JwtBearerandMicrosoft.AspNetCore.Authentication.Cookiesas direct dependencies toGiraffe.