Skip to content

Commit

Permalink
Add sample for JWT
Browse files Browse the repository at this point in the history
  • Loading branch information
Krzysztof-Cieslak committed Feb 2, 2018
1 parent 6efb0d0 commit da1fe1d
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 0 deletions.
15 changes: 15 additions & 0 deletions Saturn.sln
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sample", "sample", "{511FB3
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Saturn.Sample", "sample\Saturn.Sample\Saturn.Sample.fsproj", "{5FBE7B9D-4E1B-4ACA-B9A5-8DA88D6EF4C0}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "JWTSample", "sample\JWTSample\JWTSample.fsproj", "{C2B9E879-D1EC-49C1-A86F-0D36202454D2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -48,9 +50,22 @@ Global
{5FBE7B9D-4E1B-4ACA-B9A5-8DA88D6EF4C0}.Release|x64.Build.0 = Release|x64
{5FBE7B9D-4E1B-4ACA-B9A5-8DA88D6EF4C0}.Release|x86.ActiveCfg = Release|x86
{5FBE7B9D-4E1B-4ACA-B9A5-8DA88D6EF4C0}.Release|x86.Build.0 = Release|x86
{C2B9E879-D1EC-49C1-A86F-0D36202454D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C2B9E879-D1EC-49C1-A86F-0D36202454D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C2B9E879-D1EC-49C1-A86F-0D36202454D2}.Debug|x64.ActiveCfg = Debug|x64
{C2B9E879-D1EC-49C1-A86F-0D36202454D2}.Debug|x64.Build.0 = Debug|x64
{C2B9E879-D1EC-49C1-A86F-0D36202454D2}.Debug|x86.ActiveCfg = Debug|x86
{C2B9E879-D1EC-49C1-A86F-0D36202454D2}.Debug|x86.Build.0 = Debug|x86
{C2B9E879-D1EC-49C1-A86F-0D36202454D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C2B9E879-D1EC-49C1-A86F-0D36202454D2}.Release|Any CPU.Build.0 = Release|Any CPU
{C2B9E879-D1EC-49C1-A86F-0D36202454D2}.Release|x64.ActiveCfg = Release|x64
{C2B9E879-D1EC-49C1-A86F-0D36202454D2}.Release|x64.Build.0 = Release|x64
{C2B9E879-D1EC-49C1-A86F-0D36202454D2}.Release|x86.ActiveCfg = Release|x86
{C2B9E879-D1EC-49C1-A86F-0D36202454D2}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{8DBA089A-7C24-4E87-870B-E0774654F376} = {F2C8C347-845F-42E4-A702-7381C4B4087F}
{5FBE7B9D-4E1B-4ACA-B9A5-8DA88D6EF4C0} = {511FB392-5714-4028-97F3-F883F81B43DB}
{C2B9E879-D1EC-49C1-A86F-0D36202454D2} = {511FB392-5714-4028-97F3-F883F81B43DB}
EndGlobalSection
EndGlobal
6 changes: 6 additions & 0 deletions sample/JWTSample/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
78 changes: 78 additions & 0 deletions sample/JWTSample/JWTSample.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
module JWTSample
open System
open Saturn.Application
open Saturn.ControllerHelpers
open System.Security.Claims
open System.IdentityModel.Tokens.Jwt
open Microsoft.IdentityModel.Tokens
open Saturn.Router
open Giraffe
open Microsoft.AspNetCore.Http
open Saturn.Pipeline

//Based on https://medium.com/@dsincl12/json-web-token-with-giraffe-and-f-4cebe1c3ef3b

let secret = "spadR2dre#u-ruBrE@TepA&*Uf@U"
let issuer = "saturnframework.io"

[<CLIMutable>]
type LoginViewModel =
{
Email : string
Password : string
}

[<CLIMutable>]
type TokenResult =
{
Token : string
}

let generateToken email =
let claims = [|
Claim(JwtRegisteredClaimNames.Sub, email);
Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) |]
claims
|> Authentication.generateToken (secret, SecurityAlgorithms.HmacSha256) issuer (DateTime.UtcNow.AddHours(1.0))

let handleGetSecured =
fun (next : HttpFunc) (ctx : HttpContext) ->
let email = ctx.User.FindFirst ClaimTypes.NameIdentifier
text ("User " + email.Value + " is authorized to access this resource.") next ctx

let handlePostToken =
fun (next : HttpFunc) (ctx : HttpContext) ->
task {
let! model = ctx.BindJsonAsync<LoginViewModel>()

// authenticate user

let tokenResult = generateToken model.Email

return! json tokenResult next ctx
}

let securedRouter = scope {
pipe_through jwtAuthentication
get "/" handleGetSecured
}

let topRouter = scope {
error_handler (setStatusCode 404 >=> text "Not Found")

post "/token" handlePostToken
get "/" (text "public route")
forward "/secured" securedRouter
}

let app = application {
use_jwt_authentication secret issuer

router topRouter
url "http://0.0.0.0:8085/"
}

[<EntryPoint>]
let main _ =
run app
0
16 changes: 16 additions & 0 deletions sample/JWTSample/JWTSample.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="../../src/Saturn/Saturn.fsproj">
<Name>Saturn.fsproj</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="JWTSample.fs" />
<None Include="App.config" />
</ItemGroup>
<Import Project="..\..\.paket\Paket.Restore.targets" />
</Project>
3 changes: 3 additions & 0 deletions sample/JWTSample/paket.references
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FSharp.Core
Giraffe
Microsoft.AspNetCore

0 comments on commit da1fe1d

Please sign in to comment.