Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update for Blazor wasm RTW #1637

Merged
merged 9 commits into from
May 19, 2020
Next Next commit
Update authentication code for Blazor
  • Loading branch information
rockfordlhotka committed May 18, 2020
commit a7caa640edfb61ae4465e04bb43b0154fd0eaf2f
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Csla" Version="5.2.0-R20050802" />
<PackageReference Include="Csla" Version="5.2.0-R20051501" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System;
using Csla;
using Csla.Core;
using Csla.Security;
using ProjectTracker.Dal;

namespace ProjectTracker.BusinessLibrary.Security
{
[Serializable]
public class CredentialValidator : ReadOnlyBase<CredentialValidator>
{
public static readonly PropertyInfo<string> NameProperty = RegisterProperty<string>(nameof(Name));
public string Name
{
get => GetProperty(NameProperty);
private set => LoadProperty(NameProperty, value);
}

public static readonly PropertyInfo<string> AuthenticationTypeProperty = RegisterProperty<string>(nameof(AuthenticationType));
public string AuthenticationType
{
get => GetProperty(AuthenticationTypeProperty);
private set => LoadProperty(AuthenticationTypeProperty, value);
}

public static readonly PropertyInfo<MobileList<string>> RolesProperty = RegisterProperty<MobileList<string>>(nameof(Roles));
public MobileList<string> Roles
{
get => GetProperty(RolesProperty);
private set => LoadProperty(RolesProperty, value);
}

[Fetch]
private void Fetch(Credentials credentials, [Inject] IUserDal dal)
{
var data = dal.Fetch(credentials.Username, credentials.Password);
if (data != null)
{
AuthenticationType = "Custom";
Name = data.Username;
Roles = new MobileList<string>(data.Roles);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.ComponentModel.DataAnnotations;
using Csla;

namespace ProjectTracker.BusinessLibrary.Security
{
[Serializable]
public class Credentials : BusinessBase<Credentials>
{
public static readonly PropertyInfo<string> UsernameProperty = RegisterProperty<string>(nameof(Username));
[Required]
public string Username
{
get => GetProperty(UsernameProperty);
set => SetProperty(UsernameProperty, value);
}

public static readonly PropertyInfo<string> PasswordProperty = RegisterProperty<string>(nameof(Password));
public string Password
{
get => GetProperty(PasswordProperty);
set => SetProperty(PasswordProperty, value);
}

[Create]
[RunLocal]
private void Create()
{ }
}
}
2 changes: 0 additions & 2 deletions Samples/ProjectTracker/ProjectTracker.DalMock/UserDal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ public UserDto Fetch(string username, string password)
var result = (from r in MockDb.Users
where r.Username == username && r.Password == password
select new UserDto { Username = r.Username, Roles = r.Roles }).FirstOrDefault();
if (result == null)
throw new DataNotFoundException("User");
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@
}
<form method="post">
<div class="form-group">
<label asp-for="loginData.UserName"></label>
<input asp-for="loginData.UserName" class="form-control">
<label asp-for="credentials.Username"></label>
<input asp-for="credentials.Username" class="form-control">
<div class="invalid-feedback"></div>
</div>
<div class="form-group">
<label asp-for="loginData.Password"></label>
<input asp-for="loginData.Password" class="form-control" type="password">
<label asp-for="credentials.Password"></label>
<input asp-for="credentials.Password" class="form-control" type="password">
<div class="invalid-feedback"></div>
</div>
<button type="submit" class="btn btn-primary">Login</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using ProjectTracker.BusinessLibrary.Security;

namespace ProjectTracker.Ui.Blazor.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class LoginModel : PageModel
{
[BindProperty]
public LoginData loginData { get; set; }
public Credentials credentials { get; set; }
[BindProperty]
public string AlertMessage { get; set; } = "";

Expand All @@ -31,15 +32,17 @@ public async Task<IActionResult> OnPostAsync()
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}

var identity = await Library.Security.PTIdentity.GetPTIdentityAsync(loginData.UserName, loginData.Password);

// create claimsidentity and claimsprincipal
var baseidentity = new ClaimsIdentity(identity.AuthenticationType);
baseidentity.AddClaim(new Claim(ClaimTypes.Name, identity.Name));
if (identity.Roles != null)
foreach (var item in identity.Roles)
baseidentity.AddClaim(new Claim(ClaimTypes.Role, item));
var principal = new ClaimsPrincipal(baseidentity);
var validator =
await Csla.DataPortal.FetchAsync<CredentialValidator>(credentials);
var identity = new ClaimsIdentity(validator.AuthenticationType);
if (!string.IsNullOrWhiteSpace(validator.Name))
{
identity.AddClaim(new Claim(ClaimTypes.Name, validator.Name));
if (validator.Roles != null)
foreach (var item in validator.Roles)
identity.AddClaim(new Claim(ClaimTypes.Role, item));
}
var principal = new ClaimsPrincipal(identity);

Csla.ApplicationContext.User = principal;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
@page "/account/login"
@using System.Security.Claims
@using ProjectTracker.BusinessLibrary.Security
@using Csla
@inject Csla.Blazor.ViewModel<LoginData> vm
@inject Csla.Blazor.ViewModel<Credentials> vm
@inject Csla.Blazor.Client.Authentication.CslaUserService userService
@inject NavigationManager NavigationManager

Expand All @@ -24,8 +25,8 @@ else
</tr>
</thead>
<tbody>
<TextInputRow Property="vm.GetPropertyInfo(nameof(vm.Model.Username))" />
<TextInputRow Property="vm.GetPropertyInfo(nameof(vm.Model.Password))" InputType="password" />
<TextInputRow Property="vm.GetPropertyInfo(() => vm.Model.Username)" />
<TextInputRow Property="vm.GetPropertyInfo(() => vm.Model.Password)" InputType="password" />
</tbody>
</table>
<button @onclick="LoginUser" disabled="@(!vm.Model.IsSavable)">Login</button>
Expand All @@ -36,24 +37,28 @@ else

protected override void OnInitialized()
{
vm.ModelPropertyChanged += async (s, e) => await InvokeAsync(() => StateHasChanged());
vm.ModelPropertyChanged += async (s, e) =>
await InvokeAsync(() => StateHasChanged());
}

protected override async Task OnParametersSetAsync()
{
await vm.RefreshAsync(() => Csla.DataPortal.CreateAsync<LoginData>());
await vm.RefreshAsync(() => Csla.DataPortal.CreateAsync<Credentials>());
}

private async void LoginUser()
{
var identity = await Library.Security.PTIdentity.GetPTIdentityAsync(vm.Model.Username, vm.Model.Password);

var baseidentity = new ClaimsIdentity(identity.AuthenticationType);
baseidentity.AddClaim(new Claim(ClaimTypes.Name, identity.Name));
if (identity.Roles != null)
foreach (var item in identity.Roles)
baseidentity.AddClaim(new Claim(ClaimTypes.Role, item));
var principal = new ClaimsPrincipal(baseidentity);
var validator =
await Csla.DataPortal.FetchAsync<CredentialValidator>(vm.Model);
var identity = new ClaimsIdentity(validator.AuthenticationType);
if (!string.IsNullOrWhiteSpace(validator.Name))
{
identity.AddClaim(new Claim(ClaimTypes.Name, validator.Name));
if (validator.Roles != null)
foreach (var item in validator.Roles)
identity.AddClaim(new Claim(ClaimTypes.Role, item));
}
var principal = new ClaimsPrincipal(identity);

if (identity.IsAuthenticated)
{
Expand All @@ -66,27 +71,4 @@ else
StateHasChanged();
}
}

[Serializable]
public class LoginData : BusinessBase<LoginData>
{
public static readonly PropertyInfo<string> UsernameProperty = RegisterProperty<string>(nameof(Username));
public string Username
{
get => GetProperty(UsernameProperty);
set => SetProperty(UsernameProperty, value);
}

public static readonly PropertyInfo<string> PasswordProperty = RegisterProperty<string>(nameof(Password));
public string Password
{
get => GetProperty(PasswordProperty);
set => SetProperty(PasswordProperty, value);
}

[Create]
[RunLocal]
private void Create()
{ }
}
}