Authentication / Authorization
Who are you, anyway?
This commit is contained in:
parent
5235e5a5db
commit
c0237e1433
|
@ -1,6 +1,8 @@
|
|||
module MyPrayerJournal.App
|
||||
|
||||
open Microsoft.AspNetCore.Builder
|
||||
open Microsoft.AspNetCore.Hosting
|
||||
open Microsoft.AspNetCore.Http
|
||||
open Microsoft.AspNetCore.Localization
|
||||
open Microsoft.Extensions.Configuration
|
||||
open Microsoft.Extensions.DependencyInjection
|
||||
|
@ -31,13 +33,17 @@ type Startup(env : IHostingEnvironment) =
|
|||
ignore <| services.AddLocalization (fun options -> options.ResourcesPath <- "Resources")
|
||||
ignore <| services.AddMvc ()
|
||||
ignore <| services.AddDistributedMemoryCache ()
|
||||
ignore <| services.AddSession ()
|
||||
// RethinkDB connection
|
||||
async {
|
||||
let cfg = services.BuildServiceProvider().GetService<IOptions<AppConfig>>().Value
|
||||
let! conn = DataConfig.Connect cfg.DataConfig
|
||||
do! conn.EstablishEnvironment cfg
|
||||
ignore <| services.AddSingleton conn
|
||||
//ignore <| services.AddDistributedRethinkDBCache (fun options ->
|
||||
// options.Connection <- conn
|
||||
// options.Database <- match cfg.DataConfig.Database with null -> "" | db -> db
|
||||
// options.TableName <- "Session")
|
||||
ignore <| services.AddSession ()
|
||||
} |> Async.RunSynchronously
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
|
@ -52,8 +58,14 @@ type Startup(env : IHostingEnvironment) =
|
|||
|
||||
ignore <| app.UseStaticFiles ()
|
||||
|
||||
// Add external authentication middleware below. To configure them please see https://go.microsoft.com/fwlink/?LinkID=532715
|
||||
|
||||
ignore <| app.UseCookieAuthentication(
|
||||
CookieAuthenticationOptions(
|
||||
AuthenticationScheme = Keys.Authentication,
|
||||
LoginPath = PathString("/user/log-on"),
|
||||
AutomaticAuthenticate = true,
|
||||
AutomaticChallenge = true,
|
||||
ExpireTimeSpan = TimeSpan(2, 0, 0),
|
||||
SlidingExpiration = true))
|
||||
ignore <| app.UseMvc(fun routes ->
|
||||
ignore <| routes.MapRoute(name = "default", template = "{controller=Home}/{action=Index}/{id?}"))
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
[<RequireQualifiedAccess>]
|
||||
module MyPrayerJournal.Keys
|
||||
|
||||
/// Instance name for cookie authentication
|
||||
let Authentication = "mpj-authentication"
|
||||
|
||||
/// The current user
|
||||
let CurrentUser = "mpj-user"
|
||||
|
||||
|
|
|
@ -1,12 +1,21 @@
|
|||
namespace MyPrayerJournal.Controllers
|
||||
|
||||
open Microsoft.AspNetCore.Authorization
|
||||
open Microsoft.AspNetCore.Mvc
|
||||
open MyPrayerJournal
|
||||
open RethinkDb.Driver.Net
|
||||
|
||||
/// Home controller
|
||||
[<Authorize>]
|
||||
[<Route("")>]
|
||||
type HomeController(data : IConnection) =
|
||||
inherit ApplicationController(data)
|
||||
|
||||
[<AllowAnonymous>]
|
||||
[<HttpGet("")>]
|
||||
member this.Index() = this.View()
|
||||
member this.Index() =
|
||||
async {
|
||||
match this.HttpContext.User with
|
||||
| :? AppUser as user -> return this.View "Dashboard" :> IActionResult
|
||||
| _ -> return upcast this.View ()
|
||||
} |> Async.StartAsTask
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
namespace MyPrayerJournal.Controllers
|
||||
|
||||
open Microsoft.AspNetCore.Authorization
|
||||
open Microsoft.AspNetCore.Mvc
|
||||
open Microsoft.Extensions.Options
|
||||
open MyPrayerJournal
|
||||
|
@ -7,34 +8,42 @@ open MyPrayerJournal.ViewModels
|
|||
open RethinkDb.Driver.Net
|
||||
|
||||
/// Controller for all /user URLs
|
||||
[<Authorize>]
|
||||
[<Route("user")>]
|
||||
type UserController(data : IConnection, cfg : IOptions<AppConfig>) =
|
||||
inherit ApplicationController(data)
|
||||
|
||||
[<AllowAnonymous>]
|
||||
[<HttpGet("log-on")>]
|
||||
member this.ShowLogOn () =
|
||||
this.View(LogOnViewModel())
|
||||
|
||||
|
||||
[<AllowAnonymous>]
|
||||
[<HttpPost("log-on")>]
|
||||
[<ValidateAntiForgeryToken>]
|
||||
member this.DoLogOn (form : LogOnViewModel) =
|
||||
async {
|
||||
let! user = data.LogOnUser form.Email (User.HashPassword form.Password cfg.Value.PasswordSaltBytes)
|
||||
match user with
|
||||
| Some usr -> (* this.Session.[Keys.User] <- usr
|
||||
| Some usr -> do! this.HttpContext.Authentication.SignInAsync(Keys.Authentication, AppUser(user))
|
||||
// TODO: welcome message
|
||||
(* this.Session.[Keys.User] <- usr
|
||||
{ UserMessage.Empty with Level = Level.Info
|
||||
Message = Strings.get "LogOnSuccess" }
|
||||
|> model.AddMessage
|
||||
this.Redirect "" model |> ignore // Save the messages in the session before the Nancy redirect
|
||||
// TODO: investigate if addMessage should update the session when it's called
|
||||
return this.LoginAndRedirect (System.Guid.Parse usr.Id, fallbackRedirectUrl = "/") :> obj
|
||||
*)
|
||||
|> model.AddMessage *)
|
||||
return this.Redirect "/" :> IActionResult
|
||||
| _ -> (*{ UserMessage.Empty with Level = Level.Error
|
||||
Message = Strings.get "LogOnFailure" }
|
||||
|> model.AddMessage
|
||||
return this.Redirect "/user/log-on" model *)
|
||||
return upcast this.RedirectToAction("ShowLogOn")
|
||||
return upcast this.RedirectToAction "ShowLogOn"
|
||||
//return this.View()
|
||||
} |> Async.StartAsTask
|
||||
|
||||
[<HttpGet("log-off")>]
|
||||
member this.LogOff () =
|
||||
async {
|
||||
do! this.HttpContext.Authentication.SignOutAsync(Keys.Authentication)
|
||||
// TODO: goodbye message
|
||||
return this.LocalRedirect "/"
|
||||
} |> Async.StartAsTask
|
|
@ -1,6 +1,7 @@
|
|||
namespace MyPrayerJournal
|
||||
|
||||
open Newtonsoft.Json
|
||||
open System.Security.Claims
|
||||
open System.Security.Cryptography
|
||||
|
||||
/// A user
|
||||
|
@ -81,4 +82,11 @@ type Request = {
|
|||
|> List.sortBy (fun item -> -item.AsOf)
|
||||
|> List.map (fun item -> item.AsOf)
|
||||
|> List.head
|
||||
|
||||
|
||||
/// The user for use with identity
|
||||
[<AllowNullLiteral>]
|
||||
type AppUser(user : User option) =
|
||||
inherit ClaimsPrincipal()
|
||||
|
||||
/// The current user
|
||||
member val User = user with get
|
|
@ -3,7 +3,6 @@ namespace MyPrayerJournal.ViewModels
|
|||
//open MyPrayerJournal
|
||||
|
||||
/// Parent view model for all myPrayerJournal view models
|
||||
[<AllowNullLiteral>]
|
||||
type AppViewModel() =
|
||||
member this.Q = "X"
|
||||
(*
|
||||
|
|
|
@ -2,7 +2,6 @@ namespace MyPrayerJournal.ViewModels
|
|||
|
||||
open System.ComponentModel.DataAnnotations
|
||||
|
||||
[<AllowNullLiteral>]
|
||||
type LogOnViewModel() =
|
||||
inherit AppViewModel()
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user