Last active
March 31, 2021 23:11
-
-
Save kspeakman/81654ffb000191489f1778d344d5910f to your computer and use it in GitHub Desktop.
ASP NET from F#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// F# type alias | |
type Builder = IApplicationBuilder -> IApplicationBuilder | |
let createWebServer settings = | |
let createBuilder () = (WebHostBuilder(), []) | |
let setConfig basePath (host: IWebHostBuilder, configs: Builder list) = | |
( host | |
.ConfigureAppConfiguration(fun (_: WebHostBuilderContext) (builder: IConfigurationBuilder) -> | |
builder | |
.SetBasePath(basePath) | |
.Build() | |
|> ignore | |
) | |
, configs | |
) | |
let setJwtAuth (host: IWebHostBuilder, configs: Builder list) = | |
// disable default legacy claim mapping for WS-* | |
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear() | |
JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear() | |
( host | |
.ConfigureServices(fun (context: WebHostBuilderContext) (services: IServiceCollection) -> | |
services | |
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) | |
.AddJwtBearer(fun options -> | |
// cognito does not provide audience claim | |
options.TokenValidationParameters.ValidateAudience <- false | |
options.Authority <- settings.CognitoAuthority | |
) | |
|> ignore | |
) | |
, configs @ [ fun builder -> builder.UseAuthentication() ] | |
) | |
let setLogger (host: IWebHostBuilder, configs: Builder list) = | |
( host | |
.ConfigureLogging(fun (context: WebHostBuilderContext) (builder: ILoggingBuilder) -> | |
builder.AddSerilog(seriLogger, true) | |
|> ignore | |
) | |
, configs | |
) | |
let setKestrel (host: IWebHostBuilder, configs: Builder list) = | |
( host | |
.UseKestrel(fun (context: WebHostBuilderContext) options -> | |
options.AddServerHeader <- false | |
host.UseUrls(settings.ApiHostUrls) |> ignore | |
//options.Configure(context.Configuration.GetSection("Kestrel")) |> ignore | |
) | |
, configs | |
) | |
let corsRegex = new Regex(settings.CorsPattern, RegexOptions.Compiled) | |
let setCorsPolicy (host: IWebHostBuilder, configs: Builder list) = | |
( host | |
.ConfigureServices(fun (context: WebHostBuilderContext) (services: IServiceCollection) -> | |
services.AddCors() | |
|> ignore | |
) | |
, configs @ [ | |
fun (app: IApplicationBuilder) -> | |
app.UseCors(fun (builder: CorsPolicyBuilder) -> | |
builder | |
.SetIsOriginAllowed(fun s -> corsRegex.IsMatch(s)) | |
.WithMethods("POST") | |
// added Cookie and Content-Type for file uploads | |
.WithHeaders("Authorization", "Cookie", "Content-Type", Messages.Const.UserIdHeader) | |
.AllowCredentials() | |
|> ignore | |
) | |
] | |
) | |
let setAppRoute route (host: IWebHostBuilder, configs: Builder list) = | |
( host | |
, configs @ [ | |
fun (app: IApplicationBuilder) -> | |
app.RunFn route | |
app | |
] | |
) | |
let build (host: IWebHostBuilder, configs: Builder list) = | |
host | |
.Configure(fun (app: IApplicationBuilder) -> | |
configs | |
|> List.fold (fun x f -> f x) app | |
|> ignore | |
) | |
.Build() | |
let basePath = System.IO.Directory.GetCurrentDirectory() | |
createBuilder () | |
|> setConfig basePath | |
|> setLogger | |
|> setKestrel | |
|> setJwtAuth | |
|> setCorsPolicy | |
|> setAppRoute (App.routes settings logger) | |
|> build | |
[<EntryPoint>] | |
let main argv = | |
match settingsOpt with | |
| None -> | |
() | |
| Some settings -> | |
let webServer = createWebServer settings | |
webServer.Run() | |
#if DEBUG | |
printf "Press ENTER to exit" | |
Console.ReadLine() |> ignore | |
#endif | |
0 // return an integer exit code |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment