More work; doesn't even build at this point
Why isn't JWT documented on .NET Core..... :/
This commit is contained in:
parent
a690729cf9
commit
1154ae33b4
@ -53,8 +53,9 @@ module Configure =
|
||||
.AddAntiforgery()
|
||||
.AddSingleton<IClock>(SystemClock.Instance)
|
||||
|> ignore
|
||||
let config = svc.BuildServiceProvider().GetRequiredService<IConfiguration>()
|
||||
let config = svc.BuildServiceProvider().GetRequiredService<IConfiguration>()
|
||||
let authConfig = config.GetSection "Tokens"
|
||||
let iss = authConfig.["Issuer"]
|
||||
svc.AddAuthentication()
|
||||
.AddCookie(
|
||||
fun opts ->
|
||||
@ -62,17 +63,16 @@ module Configure =
|
||||
opts.Cookie.HttpOnly <- false
|
||||
opts.Cookie.SameSite <- SameSiteMode.Strict
|
||||
opts.SlidingExpiration <- true
|
||||
opts.ClaimsIssuer <- authConfig.["Issuer"])
|
||||
opts.ClaimsIssuer <- iss)
|
||||
.AddJwtBearer(
|
||||
fun opts ->
|
||||
opts.SaveToken <- true
|
||||
opts.ClaimsIssuer <- "PrayerTracker"
|
||||
opts.TokenValidationParameters <- TokenValidationParameters ()
|
||||
opts.TokenValidationParameters.ValidIssuer <- authConfig.["Issuer"]
|
||||
opts.TokenValidationParameters.ValidAudience <- authConfig.["Issuer"]
|
||||
opts.TokenValidationParameters.IssuerSigningKey <- SymmetricSecurityKey (Convert.FromBase64String authConfig.["Key"]))
|
||||
opts.SaveToken <- true
|
||||
opts.ClaimsIssuer <- iss
|
||||
opts.TokenValidationParameters <- TokenValidationParameters (
|
||||
ValidIssuer = iss,
|
||||
ValidAudience = iss,
|
||||
IssuerSigningKey = SymmetricSecurityKey (Convert.FromBase64String authConfig.["Key"])))
|
||||
|> ignore
|
||||
let config = svc.BuildServiceProvider().GetRequiredService<IConfiguration>()
|
||||
let crypto = config.GetSection "CookieCrypto"
|
||||
CookieCrypto (crypto.["Key"], crypto.["IV"]) |> setCrypto
|
||||
svc.AddDbContext<AppDbContext>(
|
||||
@ -195,7 +195,7 @@ module Configure =
|
||||
.UseStaticFiles()
|
||||
.UseSession()
|
||||
.UseRequestLocalization(app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>().Value)
|
||||
.UseAuthentication()
|
||||
.UseSecurityMiddleware()
|
||||
.UseGiraffe(webApp)
|
||||
|> ignore
|
||||
Views.I18N.setUpFactories <| app.ApplicationServices.GetRequiredService<IStringLocalizerFactory> ()
|
||||
|
@ -58,7 +58,9 @@ let setCrypto c = Crypto.crypto <- c
|
||||
|
||||
/// Properties stored in the Small Group cookie
|
||||
type GroupCookie =
|
||||
{ /// The Id of the small group
|
||||
{ /// The token representing the group's claims
|
||||
token : string
|
||||
/// The Id of the small group
|
||||
[<JsonProperty "g">]
|
||||
GroupId : Guid
|
||||
/// The password hash of the small group
|
||||
@ -100,8 +102,10 @@ type TimeoutCookie =
|
||||
|
||||
/// The payload for the user's "Remember Me" cookie
|
||||
type UserCookie =
|
||||
{ /// The Id of the group into to which the user is logged
|
||||
[< JsonProperty "g">]
|
||||
{ /// The token representing the current user's logged in claims
|
||||
token : string
|
||||
/// The Id of the group into to which the user is logged
|
||||
[<JsonProperty "g">]
|
||||
GroupId : Guid
|
||||
/// The Id of the user
|
||||
[<JsonProperty "i">]
|
||||
|
@ -1,6 +1,7 @@
|
||||
[<AutoOpen>]
|
||||
module PrayerTracker.Extensions
|
||||
|
||||
open Microsoft.AspNetCore.Builder
|
||||
open Microsoft.AspNetCore.Http
|
||||
open Microsoft.FSharpLu
|
||||
open Newtonsoft.Json
|
||||
@ -44,3 +45,9 @@ type ISession with
|
||||
type HttpContext with
|
||||
/// Get the EF database context from DI
|
||||
member this.dbContext () : AppDbContext = downcast this.RequestServices.GetService typeof<AppDbContext>
|
||||
|
||||
|
||||
type IApplicationBuilder with
|
||||
/// Insert the PrayerTracker custom security middleware into the request pipeline
|
||||
member this.UseSecurityMiddleware () =
|
||||
this.UseMiddleware<SecurityMiddleware>();
|
||||
|
@ -15,9 +15,10 @@
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="appsettings.json" />
|
||||
<Compile Include="Extensions.fs" />
|
||||
<Compile Include="Cookies.fs" />
|
||||
<Compile Include="Email.fs" />
|
||||
<Compile Include="SecurityMiddleware.fs" />
|
||||
<Compile Include="Extensions.fs" />
|
||||
<Compile Include="CommonFunctions.fs" />
|
||||
<Compile Include="Church.fs" />
|
||||
<Compile Include="Home.fs" />
|
||||
|
54
src/PrayerTracker/SecurityMiddleware.fs
Normal file
54
src/PrayerTracker/SecurityMiddleware.fs
Normal file
@ -0,0 +1,54 @@
|
||||
namespace PrayerTracker
|
||||
|
||||
open FSharp.Control.Tasks.V2.ContextInsensitive
|
||||
open Microsoft.AspNetCore.Http
|
||||
open Cookies
|
||||
open System.IdentityModel.Tokens.Jwt
|
||||
open System
|
||||
open System.Security.Claims
|
||||
open Microsoft.IdentityModel.Tokens
|
||||
|
||||
/// Middleware to obtain the current user or group from a cookie or the authorization header
|
||||
type SecurityMiddleware (next : RequestDelegate) =
|
||||
|
||||
/// Try to get a JWT from the user's logged in cookie
|
||||
let tryGetJwtFromUserCookie (ctx : HttpContext) =
|
||||
match UserCookie.fromPayload ctx.Request.Cookies.[Key.Cookie.user] with
|
||||
| Some cookie -> Some cookie.token
|
||||
| None -> None
|
||||
|
||||
/// Try to get a JWT from a group's logged in cookie
|
||||
let tryGetJwtFromGroupCookie (ctx : HttpContext) =
|
||||
match GroupCookie.fromPayload ctx.Request.Cookies.[Key.Cookie.group] with
|
||||
| Some cookie -> Some cookie.token
|
||||
| None -> None
|
||||
|
||||
/// Try to get a JWT from the Authorization header
|
||||
let tryGetJwtFromAuthHeader (ctx : HttpContext) =
|
||||
match ctx.Request.Headers.["Authorization"] |> Seq.tryFind (fun x -> x.StartsWith "Bearer ") with
|
||||
| Some hdr -> Some (hdr.Replace ("Bearer ", ""))
|
||||
| None -> None
|
||||
|
||||
/// Attempt to get the user either from a cookie or an Authorization header
|
||||
member __.Invoke ctx =
|
||||
task {
|
||||
let jwt =
|
||||
seq {
|
||||
tryGetJwtFromUserCookie ctx
|
||||
tryGetJwtFromGroupCookie ctx
|
||||
tryGetJwtFromAuthHeader ctx
|
||||
}
|
||||
|> Seq.tryFind Option.isSome
|
||||
|> Option.flatten
|
||||
match jwt with
|
||||
| Some token ->
|
||||
let handler = JwtSecurityTokenHandler ()
|
||||
let mutable x : JwtSecurityToken ref = JwtSecurityToken () // does not build
|
||||
let usr = handler.ValidateToken(token, TokenValidationParameters (), x) // JwtSecurityTokenHandler. ClaimsPrincipal ()
|
||||
ctx.User <- usr
|
||||
()
|
||||
| None -> ()
|
||||
do! next.Invoke ctx
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user