How did I create this sample?
Essentially it's
dotnet new webapi -lang f#
Then porting calls as seen in 1_ClientCredentials to f#.
How did I create this sample?
Essentially it's
dotnet new webapi -lang f#
Then porting calls as seen in 1_ClientCredentials to f#.
| { | |
| "Logging": { | |
| "LogLevel": { | |
| "Default": "Debug", | |
| "System": "Information", | |
| "Microsoft": "Information" | |
| } | |
| } | |
| } |
| { | |
| "Logging": { | |
| "LogLevel": { | |
| "Default": "Warning" | |
| } | |
| }, | |
| "AllowedHosts": "*" | |
| } |
| namespace identity.Controllers | |
| open System | |
| open System.Collections.Generic | |
| open System.Linq | |
| open System.Threading.Tasks | |
| open Microsoft.AspNetCore.Mvc | |
| [<Route("api/[controller]")>] | |
| [<ApiController>] | |
| type ValuesController () = | |
| inherit ControllerBase() | |
| [<HttpGet>] | |
| member this.Get() = | |
| let values = [|"value1"; "value2"|] | |
| ActionResult<string[]>(values) | |
| [<HttpGet("{id}")>] | |
| member this.Get(id:int) = | |
| let value = "value" | |
| ActionResult<string>(value) | |
| [<HttpPost>] | |
| member this.Post([<FromBody>] value:string) = | |
| () | |
| [<HttpPut("{id}")>] | |
| member this.Put(id:int, [<FromBody>] value:string ) = | |
| () | |
| [<HttpDelete("{id}")>] | |
| member this.Delete(id:int) = | |
| () |
| <Project Sdk="Microsoft.NET.Sdk.Web"> | |
| <PropertyGroup> | |
| <TargetFramework>netcoreapp2.2</TargetFramework> | |
| <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel> | |
| </PropertyGroup> | |
| <ItemGroup> | |
| <Compile Include="Controllers/ValuesController.fs" /> | |
| <Compile Include="Startup.fs" /> | |
| <Compile Include="Program.fs" /> | |
| </ItemGroup> | |
| <ItemGroup> | |
| <PackageReference Include="Microsoft.AspNetCore.App" /> | |
| <PackageReference Include="IdentityServer4" Version="2.3.0" /> | |
| <PackageReference Include="Serilog" Version="2.7.1" /> | |
| <PackageReference Include="Serilog.AspNetCore" Version="2.1.1" /> | |
| <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> | |
| <PackageReference Include="Serilog.Sinks.File" Version="4.0.0" /> | |
| </ItemGroup> | |
| </Project> |
| namespace identity | |
| open System | |
| open System.Collections.Generic | |
| open System.IO | |
| open System.Linq | |
| open System.Threading.Tasks | |
| open Microsoft.AspNetCore | |
| open Microsoft.AspNetCore.Hosting | |
| open Microsoft.Extensions.Configuration | |
| open Microsoft.Extensions.Logging | |
| open Serilog | |
| open Serilog.Events | |
| open Serilog.Sinks.SystemConsole.Themes | |
| module Program = | |
| let exitCode = 0 | |
| Console.Title <- "IdentityServer4" | |
| let CreateWebHostBuilder args = | |
| WebHost | |
| .CreateDefaultBuilder(args) | |
| .UseStartup<Startup>() | |
| .UseSerilog(Action<WebHostBuilderContext,LoggerConfiguration>(fun context configuration -> | |
| configuration | |
| .MinimumLevel.Debug() | |
| .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) | |
| .MinimumLevel.Override("System", LogEventLevel.Warning) | |
| .MinimumLevel.Override("Microsoft.AspNetCore.Authentication", LogEventLevel.Information) | |
| .Enrich.FromLogContext() | |
| .WriteTo.File(@"identityserver4_log.txt") | |
| .WriteTo.Console(outputTemplate= "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme= AnsiConsoleTheme.Literate) | |
| |> ignore | |
| )) | |
| [<EntryPoint>] | |
| let main args = | |
| CreateWebHostBuilder(args).Build().Run() | |
| exitCode |
| { | |
| "$schema": "http://json.schemastore.org/launchsettings.json", | |
| "iisSettings": { | |
| "windowsAuthentication": false, | |
| "anonymousAuthentication": true, | |
| "iisExpress": { | |
| "applicationUrl": "http://localhost:62656", | |
| "sslPort": 44333 | |
| } | |
| }, | |
| "profiles": { | |
| "IIS Express": { | |
| "commandName": "IISExpress", | |
| "launchBrowser": true, | |
| "launchUrl": "api/values", | |
| "environmentVariables": { | |
| "ASPNETCORE_ENVIRONMENT": "Development" | |
| } | |
| }, | |
| "identity": { | |
| "commandName": "Project", | |
| "launchBrowser": true, | |
| "launchUrl": "api/values", | |
| "applicationUrl": "https://localhost:5001;http://localhost:5000", | |
| "environmentVariables": { | |
| "ASPNETCORE_ENVIRONMENT": "Development" | |
| } | |
| } | |
| } | |
| } |
| namespace identity | |
| open System | |
| open System.Collections.Generic | |
| open System.Linq | |
| open System.Threading.Tasks | |
| open Microsoft.AspNetCore.Builder | |
| open Microsoft.AspNetCore.Hosting | |
| open Microsoft.AspNetCore.HttpsPolicy; | |
| open Microsoft.AspNetCore.Mvc | |
| open Microsoft.Extensions.Configuration | |
| open Microsoft.Extensions.DependencyInjection | |
| module Config = | |
| open IdentityServer4.Models | |
| let getIdentityResources() : seq<IdentityResource>=seq{ | |
| yield IdentityResources.OpenId() | |
| } | |
| let getApis(): seq<ApiResource>=seq{ | |
| yield ApiResource("api1", "My API") | |
| } | |
| let getClients(): seq<Client>=seq{ | |
| let c = Client() | |
| c.ClientId <- "client" | |
| // no interactive user, use the clientid/secret for authentication | |
| c.AllowedGrantTypes <- GrantTypes.ClientCredentials | |
| // secret for authentication | |
| c.ClientSecrets.Add (Secret("secret".Sha256())) | |
| // scopes that client has access to | |
| c.AllowedScopes.Add "api1" | |
| yield c | |
| } | |
| type Startup private () = | |
| new (configuration: IConfiguration, environment:IHostingEnvironment) as this = | |
| Startup() then | |
| this.Configuration <- configuration | |
| this.env <- environment | |
| // This method gets called by the runtime. Use this method to add services to the container. | |
| member this.ConfigureServices(services: IServiceCollection) = | |
| // Add framework services. | |
| services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2) |> ignore | |
| let id4Builder = | |
| services.AddIdentityServer() | |
| .AddInMemoryIdentityResources(Config.getIdentityResources()) | |
| .AddInMemoryApiResources(Config.getApis()) | |
| .AddInMemoryClients(Config.getClients()) | |
| if (this.env.IsDevelopment()) then | |
| id4Builder.AddDeveloperSigningCredential() |> ignore | |
| else | |
| failwith "need to configure key material" | |
| // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | |
| member this.Configure(app: IApplicationBuilder, env: IHostingEnvironment) = | |
| if (env.IsDevelopment()) then | |
| app.UseDeveloperExceptionPage() |> ignore | |
| else | |
| // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. | |
| app.UseHsts() |> ignore | |
| app.UseHttpsRedirection() |> ignore | |
| app.UseIdentityServer() |> ignore | |
| app.UseMvc() |> ignore | |
| member val Configuration : IConfiguration = null with get, set | |
| member val private env : IHostingEnvironment = null with get, set |