* [Fixes #17014] Add an auth-enabled template for Blazor WASM projects * The template enables auth using cookies. * Includes a UserController to return the user claims/data to the user * Includes an IdentityAuthenticationStateProvider that fetches the claims data from the application. * It requires a hosted project.
This commit is contained in:
parent
4ab5fe6803
commit
e64b8a91ad
|
|
@ -204,6 +204,10 @@
|
|||
<SystemThreadingTasksExtensionsPackageVersion>4.5.2</SystemThreadingTasksExtensionsPackageVersion>
|
||||
<!-- Packages developed by @aspnet, but manually updated as necessary. -->
|
||||
<LibuvPackageVersion>1.10.0</LibuvPackageVersion>
|
||||
<MicrosoftAspNetCoreIdentityUIPackageVersion>3.1.0</MicrosoftAspNetCoreIdentityUIPackageVersion>
|
||||
<MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion>3.1.0</MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion>
|
||||
<MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion>3.1.0</MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion>
|
||||
<MicrosoftAspNetCoreComponentsAuthorizationPackageVersion>3.1.0</MicrosoftAspNetCoreComponentsAuthorizationPackageVersion>
|
||||
<MicrosoftAspNetWebApiClientPackageVersion>5.2.6</MicrosoftAspNetWebApiClientPackageVersion>
|
||||
<!-- Partner teams -->
|
||||
<MicrosoftAzureKeyVaultPackageVersion>2.3.2</MicrosoftAzureKeyVaultPackageVersion>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.Blazor.Build" Version="${MicrosoftAspNetCoreBlazorBuildPackageVersion}" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Blazor.DevServer" Version="${MicrosoftAspNetCoreBlazorDevServerPackageVersion}" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Blazor.HttpClient" Version="${MicrosoftAspNetCoreBlazorHttpClientPackageVersion}" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="${MicrosoftAspNetCoreComponentsAuthorizationPackageVersion}" Condition="'$(IndividualLocalAuth)' == 'true'" />
|
||||
</ItemGroup>
|
||||
<!--#if Hosted -->
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -13,4 +13,21 @@
|
|||
<ProjectReference Include="..\Shared\BlazorWasm-CSharp.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--#if (IndividualLocalAuth && !UseLocalDB) -->
|
||||
<ItemGroup>
|
||||
<None Update="app.db" CopyToOutputDirectory="PreserveNewest" ExcludeFromSingleFile="true" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--#endif -->
|
||||
<!--#if (IndividualLocalAuth) -->
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="${MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion}" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="${MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion}" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="${MicrosoftAspNetCoreIdentityUIPackageVersion}" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="${MicrosoftEntityFrameworkCoreSqlServerPackageVersion}" Condition="'$(UseLocalDB)' == 'True'" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="${MicrosoftEntityFrameworkCoreSqlitePackageVersion}" Condition="'$(UseLocalDB)' != 'True'" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="${MicrosoftEntityFrameworkCoreToolsPackageVersion}" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--#endif -->
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -20,9 +20,15 @@
|
|||
MicrosoftAspNetCoreBlazorBuildPackageVersion=$(MicrosoftAspNetCoreBlazorBuildPackageVersion);
|
||||
MicrosoftAspNetCoreBlazorDevServerPackageVersion=$(MicrosoftAspNetCoreBlazorDevServerPackageVersion);
|
||||
MicrosoftAspNetCoreBlazorHttpClientPackageVersion=$(MicrosoftAspNetCoreBlazorHttpClientPackageVersion);
|
||||
MonoWebAssemblyInteropPackageVersion=$(MonoWebAssemblyInteropPackageVersion);
|
||||
MicrosoftEntityFrameworkCoreSqlServerPackageVersion=$(MicrosoftEntityFrameworkCoreSqlServerPackageVersion);
|
||||
MicrosoftAspNetCoreBlazorServerPackageVersion=$(MicrosoftAspNetCoreBlazorServerPackageVersion);
|
||||
MicrosoftAspNetCoreComponentsAuthorizationPackageVersion=$(MicrosoftAspNetCoreComponentsAuthorizationPackageVersion);
|
||||
MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion=$(MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion);
|
||||
MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion=$(MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion);
|
||||
MicrosoftAspNetCoreIdentityUIPackageVersion=$(MicrosoftAspNetCoreIdentityUIPackageVersion);
|
||||
MicrosoftEntityFrameworkCoreSqlServerPackageVersion=$(MicrosoftEntityFrameworkCoreSqlServerPackageVersion);
|
||||
MicrosoftEntityFrameworkCoreSqlitePackageVersion=$(MicrosoftEntityFrameworkCoreSqlitePackageVersion);
|
||||
MicrosoftEntityFrameworkCoreToolsPackageVersion=$(MicrosoftEntityFrameworkCoreToolsPackageVersion);
|
||||
MonoWebAssemblyInteropPackageVersion=$(MonoWebAssemblyInteropPackageVersion);
|
||||
</GeneratedContentProperties>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -5,11 +5,31 @@
|
|||
"longName": "no-restore",
|
||||
"shortName": ""
|
||||
},
|
||||
"Hosted": {
|
||||
"longName": "hosted"
|
||||
},
|
||||
"Hosted": {
|
||||
"longName": "hosted"
|
||||
},
|
||||
"Framework": {
|
||||
"longName": "framework"
|
||||
},
|
||||
"UseLocalDB": {
|
||||
"longName": "use-local-db"
|
||||
},
|
||||
"HttpPort": {
|
||||
"isHidden": true
|
||||
},
|
||||
"HttpsPort": {
|
||||
"isHidden": true
|
||||
},
|
||||
"ExcludeLaunchSettings": {
|
||||
"longName": "exclude-launch-settings",
|
||||
"shortName": ""
|
||||
},
|
||||
"UserSecretsId": {
|
||||
"isHidden": true
|
||||
},
|
||||
"NoHttps": {
|
||||
"longName": "no-https",
|
||||
"shortName": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,82 @@
|
|||
"exclude": [
|
||||
"*.sln"
|
||||
]
|
||||
},
|
||||
{
|
||||
"condition": "(!IndividualLocalAuth || UseLocalDB)",
|
||||
"exclude": [
|
||||
"Server/app.db"
|
||||
]
|
||||
},
|
||||
{
|
||||
"condition": "(!IndividualLocalAuth)",
|
||||
"exclude": [
|
||||
"Server/Data/SqlLite/**",
|
||||
"Server/Data/SqlServer/**",
|
||||
"Server/Data/ApplicationDbContext.cs",
|
||||
"Server/Areas/**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"condition": "(IndividualLocalAuth && UseLocalDB)",
|
||||
"rename": {
|
||||
"Server/Data/SqlServer/": "Server/Data/Migrations/"
|
||||
},
|
||||
"exclude": [
|
||||
"Server/Data/SqlLite/**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"condition": "(IndividualLocalAuth && !UseLocalDB)",
|
||||
"rename": {
|
||||
"Server/Data/SqlLite/": "Server/Data/Migrations/"
|
||||
},
|
||||
"exclude": [
|
||||
"Server/Data/SqlServer/**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"condition": "(NoAuth && Hosted)",
|
||||
"rename": {
|
||||
"Client/Shared/MainLayout.NoAuth.razor": "Client/Shared/MainLayout.razor"
|
||||
},
|
||||
"exclude": [
|
||||
"Client/Shared/LoginDisplay.*.razor",
|
||||
"Client/Shared/MainLayout.Auth.razor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"condition": "(!Hosted)",
|
||||
"rename": {
|
||||
"Client/Shared/MainLayout.NoAuth.razor": "Shared/MainLayout.razor"
|
||||
},
|
||||
"exclude": [
|
||||
"Client/Shared/LoginDisplay.*.razor",
|
||||
"Client/Shared/MainLayout.Auth.razor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"condition": "(!NoAuth && Hosted)",
|
||||
"rename": {
|
||||
"Client/Shared/MainLayout.Auth.razor": "Client/Shared/MainLayout.razor"
|
||||
},
|
||||
"exclude": [
|
||||
"Client/Shared/MainLayout.NoAuth.razor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"condition": "(IndividualLocalAuth)",
|
||||
"rename": {
|
||||
"Client/Shared/LoginDisplay.IndividualLocalAuth.razor": "Client/Shared/LoginDisplay.razor"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "(NoAuth)",
|
||||
"exclude": [
|
||||
"Client/Services/HostAuthenticationStateProvider.cs",
|
||||
"Server/Controllers/UserController.cs",
|
||||
"Shared/Authorization/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -107,6 +183,111 @@
|
|||
"datatype": "bool",
|
||||
"defaultValue": "false",
|
||||
"description": "If specified, includes an ASP.NET Core host for the Blazor app."
|
||||
},
|
||||
"auth": {
|
||||
"type": "parameter",
|
||||
"datatype": "choice",
|
||||
"choices": [
|
||||
{
|
||||
"choice": "None",
|
||||
"description": "No authentication"
|
||||
},
|
||||
{
|
||||
"choice": "Individual",
|
||||
"description": "Individual authentication"
|
||||
}
|
||||
],
|
||||
"defaultValue": "None",
|
||||
"description": "The type of authentication to use"
|
||||
},
|
||||
"UserSecretsId": {
|
||||
"type": "parameter",
|
||||
"datatype": "string",
|
||||
"replaces": "aspnet-BlazorServerWeb-CSharp-53bc9b9d-9d6a-45d4-8429-2a2761773502",
|
||||
"defaultValue": "aspnet-BlazorServerWeb-CSharp-53bc9b9d-9d6a-45d4-8429-2a2761773502",
|
||||
"description": "The ID to use for secrets (use with OrgReadAccess or Individual auth)."
|
||||
},
|
||||
"ExcludeLaunchSettings": {
|
||||
"type": "parameter",
|
||||
"datatype": "bool",
|
||||
"defaultValue": "false",
|
||||
"description": "Whether to exclude launchSettings.json from the generated template."
|
||||
},
|
||||
"HttpPort": {
|
||||
"type": "parameter",
|
||||
"datatype": "integer",
|
||||
"description": "Port number to use for the HTTP endpoint in launchSettings.json."
|
||||
},
|
||||
"HttpPortGenerated": {
|
||||
"type": "generated",
|
||||
"generator": "port"
|
||||
},
|
||||
"HttpPortReplacer": {
|
||||
"type": "generated",
|
||||
"generator": "coalesce",
|
||||
"parameters": {
|
||||
"sourceVariableName": "HttpPort",
|
||||
"fallbackVariableName": "HttpPortGenerated"
|
||||
},
|
||||
"replaces": "8080"
|
||||
},
|
||||
"HttpsPort": {
|
||||
"type": "parameter",
|
||||
"datatype": "integer",
|
||||
"description": "Port number to use for the HTTPS endpoint in launchSettings.json. This option is only applicable when the parameter no-https is not used (no-https will be ignored if either IndividualAuth or OrganizationalAuth is used)."
|
||||
},
|
||||
"HttpsPortGenerated": {
|
||||
"type": "generated",
|
||||
"generator": "port",
|
||||
"parameters": {
|
||||
"low": 44300,
|
||||
"high": 44399
|
||||
}
|
||||
},
|
||||
"HttpsPortReplacer": {
|
||||
"type": "generated",
|
||||
"generator": "coalesce",
|
||||
"parameters": {
|
||||
"sourceVariableName": "HttpsPort",
|
||||
"fallbackVariableName": "HttpsPortGenerated"
|
||||
},
|
||||
"replaces": "44300"
|
||||
},
|
||||
"IndividualLocalAuth": {
|
||||
"type": "computed",
|
||||
"value": "(auth == \"Individual\")"
|
||||
},
|
||||
"NoAuth": {
|
||||
"type": "computed",
|
||||
"value": "(!(IndividualAuth))"
|
||||
},
|
||||
"IndividualAuth": {
|
||||
"type": "computed",
|
||||
"value": "(IndividualLocalAuth)"
|
||||
},
|
||||
"RequiresHttps": {
|
||||
"type": "computed",
|
||||
"value": "(IndividualAuth || !NoHttps)"
|
||||
},
|
||||
"NoHttps": {
|
||||
"type": "parameter",
|
||||
"datatype": "bool",
|
||||
"defaultValue": "false",
|
||||
"description": "Whether to turn off HTTPS. This option only applies if Individual, IndividualB2C, SingleOrg, or MultiOrg aren't used for --auth."
|
||||
},
|
||||
"UseLocalDB": {
|
||||
"type": "parameter",
|
||||
"datatype": "bool",
|
||||
"defaultValue": "false",
|
||||
"description": "Whether to use LocalDB instead of SQLite. This option only applies if --auth Individual or --auth IndividualB2C is specified."
|
||||
},
|
||||
"copyrightYear": {
|
||||
"type": "generated",
|
||||
"generator": "now",
|
||||
"replaces": "copyrightYear",
|
||||
"parameters": {
|
||||
"format": "yyyy"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,30 @@
|
|||
"additionalWizardParameters": {
|
||||
"$isMultiProjectTemplate$": "true"
|
||||
},
|
||||
"supportedAuthentications": [
|
||||
{
|
||||
"auth": "None",
|
||||
"authenticationType": "NoAuth",
|
||||
"allowUnsecured": true
|
||||
},
|
||||
{
|
||||
"auth": "Individual",
|
||||
"authenticationType": "IndividualAuth",
|
||||
"b2cAuthenticationOptions": "Local"
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"name": "HttpPort",
|
||||
"useHttps": false
|
||||
},
|
||||
{
|
||||
"name": "HttpsPort",
|
||||
"useHttps": true
|
||||
}
|
||||
],
|
||||
"excludeLaunchSettings": false,
|
||||
"disableHttpsSymbol": "NoHttps",
|
||||
"symbolInfo": [
|
||||
{
|
||||
"id": "Hosted",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
<Router AppAssembly="@typeof(Program).Assembly">
|
||||
@*#if (NoAuth)
|
||||
<Router AppAssembly="@typeof(Program).Assembly">
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||
</Found>
|
||||
|
|
@ -8,3 +9,17 @@
|
|||
</LayoutView>
|
||||
</NotFound>
|
||||
</Router>
|
||||
#else
|
||||
<CascadingAuthenticationState>
|
||||
<Router AppAssembly="@typeof(Program).Assembly">
|
||||
<Found Context="routeData">
|
||||
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||
</Found>
|
||||
<NotFound>
|
||||
<LayoutView Layout="@typeof(MainLayout)">
|
||||
<p>Sorry, there's nothing at this address.</p>
|
||||
</LayoutView>
|
||||
</NotFound>
|
||||
</Router>
|
||||
</CascadingAuthenticationState>
|
||||
#endif*@
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
@page "/fetchdata"
|
||||
@*#if (!NoAuth)
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
#endif*@
|
||||
@*#if (Hosted)
|
||||
@using BlazorWasm_CSharp.Shared
|
||||
#endif*@
|
||||
@*#if (!NoAuth)
|
||||
@attribute [Authorize]
|
||||
#endif*@
|
||||
@inject HttpClient Http
|
||||
|
||||
<h1>Weather forecast</h1>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
using BlazorWasm_CSharp.Shared.Authorization;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using System.Net.Http;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BlazorWasm_CSharp.Client
|
||||
{
|
||||
public class HostAuthenticationStateProvider : AuthenticationStateProvider
|
||||
{
|
||||
private readonly HttpClient _client;
|
||||
private ClaimsPrincipal _currentUser;
|
||||
|
||||
public HostAuthenticationStateProvider(HttpClient client)
|
||||
{
|
||||
_client = client;
|
||||
}
|
||||
|
||||
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
|
||||
{
|
||||
if (_currentUser == null)
|
||||
{
|
||||
await FetchUser();
|
||||
}
|
||||
|
||||
return new AuthenticationState(_currentUser);
|
||||
}
|
||||
|
||||
private async Task FetchUser()
|
||||
{
|
||||
var user = await _client.GetJsonAsync<UserInfo>("User");
|
||||
|
||||
if (!user.IsAuthenticated)
|
||||
{
|
||||
_currentUser = new ClaimsPrincipal(new ClaimsIdentity());
|
||||
return;
|
||||
}
|
||||
|
||||
var identity = new ClaimsIdentity(
|
||||
nameof(HostAuthenticationStateProvider),
|
||||
user.NameClaimType,
|
||||
user.RoleClaimType);
|
||||
|
||||
if (user.Claims != null)
|
||||
{
|
||||
foreach (var claim in user.Claims)
|
||||
{
|
||||
identity.AddClaim(new Claim(claim.Type, claim.Value));
|
||||
}
|
||||
}
|
||||
|
||||
_currentUser = new ClaimsPrincipal(identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<AuthorizeView>
|
||||
<Authorized>
|
||||
<a href="Identity/Account/Manage">Hello, @context.User.Identity.Name!</a>
|
||||
<form method="post" action="Identity/Account/LogOut">
|
||||
<button type="submit" class="nav-link btn btn-link">Log out</button>
|
||||
</form>
|
||||
</Authorized>
|
||||
<NotAuthorized>
|
||||
<a href="Identity/Account/Register">Register</a>
|
||||
<a href="Identity/Account/Login">Log in</a>
|
||||
</NotAuthorized>
|
||||
</AuthorizeView>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
@inherits LayoutComponentBase
|
||||
|
||||
<div class="sidebar">
|
||||
<NavMenu />
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
<div class="top-row px-4 auth">
|
||||
<LoginDisplay />
|
||||
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
|
||||
</div>
|
||||
|
||||
<div class="content px-4">
|
||||
@Body
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
#if (!NoAuth)
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
#endif
|
||||
using Microsoft.AspNetCore.Components.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
|
|
@ -11,6 +14,10 @@ namespace BlazorWasm_CSharp
|
|||
{
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
#if (IndividualLocalAuth)
|
||||
services.AddAuthorizationCore();
|
||||
services.AddSingleton<AuthenticationStateProvider, HostAuthenticationStateProvider>();
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Configure(IComponentsApplicationBuilder app)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
@using System.Net.Http
|
||||
@*#if (!NoAuth)
|
||||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
#endif*@
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
|
|
@ -0,0 +1,15 @@
|
|||
@page
|
||||
@using Microsoft.AspNetCore.Identity
|
||||
@attribute [IgnoreAntiforgeryToken]
|
||||
@inject SignInManager<IdentityUser> SignInManager
|
||||
@functions {
|
||||
public async Task<IActionResult> OnPost()
|
||||
{
|
||||
if (SignInManager.IsSignedIn(User))
|
||||
{
|
||||
await SignInManager.SignOutAsync();
|
||||
}
|
||||
|
||||
return Redirect("~/");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
@using Microsoft.AspNetCore.Identity
|
||||
@inject SignInManager<IdentityUser> SignInManager
|
||||
@inject UserManager<IdentityUser> UserManager
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
||||
<ul class="navbar-nav">
|
||||
@if (SignInManager.IsSignedIn(User))
|
||||
{
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @User.Identity.Name!</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="/" method="post">
|
||||
<button type="submit" class="nav-link btn btn-link text-dark">Logout</button>
|
||||
</form>
|
||||
</li>
|
||||
}
|
||||
else
|
||||
{
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using BlazorWasm_CSharp.Shared.Authorization;
|
||||
|
||||
namespace BlazorWasm_CSharp.Server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
public class UserController : ControllerBase
|
||||
{
|
||||
[HttpGet("/User")]
|
||||
[Authorize]
|
||||
[AllowAnonymous]
|
||||
public IActionResult GetCurrentUser() =>
|
||||
Ok(User.Identity.IsAuthenticated ? CreateUserInfo(User) : UserInfo.Anonymous);
|
||||
|
||||
private UserInfo CreateUserInfo(ClaimsPrincipal claimsPrincipal)
|
||||
{
|
||||
if (!claimsPrincipal.Identity.IsAuthenticated)
|
||||
{
|
||||
return UserInfo.Anonymous;
|
||||
}
|
||||
|
||||
var userInfo = new UserInfo();
|
||||
userInfo.IsAuthenticated = true;
|
||||
|
||||
if (claimsPrincipal.Identity is ClaimsIdentity claimsIdentity)
|
||||
{
|
||||
userInfo.NameClaimType = claimsIdentity.NameClaimType;
|
||||
userInfo.RoleClaimType = claimsIdentity.RoleClaimType;
|
||||
}
|
||||
else
|
||||
{
|
||||
userInfo.NameClaimType = "name";
|
||||
userInfo.RoleClaimType = "roles";
|
||||
}
|
||||
|
||||
if (claimsPrincipal.Claims.Any())
|
||||
{
|
||||
var claims = new List<ClaimValue>();
|
||||
var nameClaims = claimsPrincipal.FindAll(userInfo.NameClaimType);
|
||||
foreach (var claim in nameClaims)
|
||||
{
|
||||
claims.Add(new ClaimValue(userInfo.NameClaimType, claim.Value));
|
||||
}
|
||||
|
||||
// Uncomment this code if you want to send additional claims to the client.
|
||||
//foreach (var claim in claimsPrincipal.Claims.Except(nameClaims))
|
||||
//{
|
||||
// claims.Add(new ClaimValue(claim.Type, claim.Value));
|
||||
//}
|
||||
|
||||
userInfo.Claims = claims;
|
||||
}
|
||||
|
||||
return userInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,11 +3,17 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
#if (!NoAuth)
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
#endif
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace BlazorWasm_CSharp.Server.Controllers
|
||||
{
|
||||
#if (!NoAuth)
|
||||
[Authorize]
|
||||
#endif
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class WeatherForecastController : ControllerBase
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace BlazorWasm_CSharp.Server.Data
|
||||
{
|
||||
public class ApplicationDbContext : IdentityDbContext
|
||||
{
|
||||
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
|
||||
: base(options)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,270 @@
|
|||
// <auto-generated />
|
||||
using System;
|
||||
using BlazorWasm_CSharp.Server.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
namespace BlazorWasm_CSharp.Server.Data.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("00000000000000_CreateIdentitySchema")]
|
||||
partial class CreateIdentitySchema
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "3.0.0");
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasName("RoleNameIndex");
|
||||
|
||||
b.ToTable("AspNetRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasName("UserNameIndex");
|
||||
|
||||
b.ToTable("AspNetUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(128);
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(128);
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(128);
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(128);
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace BlazorWasm_CSharp.Server.Data.Migrations
|
||||
{
|
||||
public partial class CreateIdentitySchema : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetRoles",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<string>(nullable: false),
|
||||
Name = table.Column<string>(maxLength: 256, nullable: true),
|
||||
NormalizedName = table.Column<string>(maxLength: 256, nullable: true),
|
||||
ConcurrencyStamp = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUsers",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<string>(nullable: false),
|
||||
UserName = table.Column<string>(maxLength: 256, nullable: true),
|
||||
NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),
|
||||
Email = table.Column<string>(maxLength: 256, nullable: true),
|
||||
NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),
|
||||
EmailConfirmed = table.Column<bool>(nullable: false),
|
||||
PasswordHash = table.Column<string>(nullable: true),
|
||||
SecurityStamp = table.Column<string>(nullable: true),
|
||||
ConcurrencyStamp = table.Column<string>(nullable: true),
|
||||
PhoneNumber = table.Column<string>(nullable: true),
|
||||
PhoneNumberConfirmed = table.Column<bool>(nullable: false),
|
||||
TwoFactorEnabled = table.Column<bool>(nullable: false),
|
||||
LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
|
||||
LockoutEnabled = table.Column<bool>(nullable: false),
|
||||
AccessFailedCount = table.Column<int>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetRoleClaims",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
RoleId = table.Column<string>(nullable: false),
|
||||
ClaimType = table.Column<string>(nullable: true),
|
||||
ClaimValue = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
|
||||
column: x => x.RoleId,
|
||||
principalTable: "AspNetRoles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserClaims",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
UserId = table.Column<string>(nullable: false),
|
||||
ClaimType = table.Column<string>(nullable: true),
|
||||
ClaimValue = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserLogins",
|
||||
columns: table => new
|
||||
{
|
||||
LoginProvider = table.Column<string>(maxLength: 128, nullable: false),
|
||||
ProviderKey = table.Column<string>(maxLength: 128, nullable: false),
|
||||
ProviderDisplayName = table.Column<string>(nullable: true),
|
||||
UserId = table.Column<string>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserRoles",
|
||||
columns: table => new
|
||||
{
|
||||
UserId = table.Column<string>(nullable: false),
|
||||
RoleId = table.Column<string>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
|
||||
column: x => x.RoleId,
|
||||
principalTable: "AspNetRoles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserTokens",
|
||||
columns: table => new
|
||||
{
|
||||
UserId = table.Column<string>(nullable: false),
|
||||
LoginProvider = table.Column<string>(maxLength: 128, nullable: false),
|
||||
Name = table.Column<string>(maxLength: 128, nullable: false),
|
||||
Value = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetRoleClaims_RoleId",
|
||||
table: "AspNetRoleClaims",
|
||||
column: "RoleId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "RoleNameIndex",
|
||||
table: "AspNetRoles",
|
||||
column: "NormalizedName",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetUserClaims_UserId",
|
||||
table: "AspNetUserClaims",
|
||||
column: "UserId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetUserLogins_UserId",
|
||||
table: "AspNetUserLogins",
|
||||
column: "UserId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetUserRoles_RoleId",
|
||||
table: "AspNetUserRoles",
|
||||
column: "RoleId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "EmailIndex",
|
||||
table: "AspNetUsers",
|
||||
column: "NormalizedEmail");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "UserNameIndex",
|
||||
table: "AspNetUsers",
|
||||
column: "NormalizedUserName",
|
||||
unique: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetRoleClaims");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetUserClaims");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetUserLogins");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetUserRoles");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetUserTokens");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetRoles");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetUsers");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,268 @@
|
|||
// <auto-generated />
|
||||
using System;
|
||||
using BlazorWasm_CSharp.Server.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
namespace BlazorWasm_CSharp.Server.Data.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
partial class ApplicationDbContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "3.0.0");
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasName("RoleNameIndex");
|
||||
|
||||
b.ToTable("AspNetRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasName("UserNameIndex");
|
||||
|
||||
b.ToTable("AspNetUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(128);
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(128);
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(128);
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(128);
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,277 @@
|
|||
// <auto-generated />
|
||||
using System;
|
||||
using BlazorWasm_CSharp.Server.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
namespace BlazorWasm_CSharp.Server.Data.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("00000000000000_CreateIdentitySchema")]
|
||||
partial class CreateIdentitySchema
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "3.0.0")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128)
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(256)")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasColumnType("nvarchar(256)")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasName("RoleNameIndex")
|
||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
||||
|
||||
b.ToTable("AspNetRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasColumnType("nvarchar(256)")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("datetimeoffset");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasColumnType("nvarchar(256)")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasColumnType("nvarchar(256)")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasColumnType("nvarchar(256)")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasName("UserNameIndex")
|
||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
||||
|
||||
b.ToTable("AspNetUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("nvarchar(128)")
|
||||
.HasMaxLength(128);
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("nvarchar(128)")
|
||||
.HasMaxLength(128);
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("nvarchar(128)")
|
||||
.HasMaxLength(128);
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(128)")
|
||||
.HasMaxLength(128);
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace BlazorWasm_CSharp.Server.Data.Migrations
|
||||
{
|
||||
public partial class CreateIdentitySchema : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetRoles",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<string>(nullable: false),
|
||||
Name = table.Column<string>(maxLength: 256, nullable: true),
|
||||
NormalizedName = table.Column<string>(maxLength: 256, nullable: true),
|
||||
ConcurrencyStamp = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUsers",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<string>(nullable: false),
|
||||
UserName = table.Column<string>(maxLength: 256, nullable: true),
|
||||
NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),
|
||||
Email = table.Column<string>(maxLength: 256, nullable: true),
|
||||
NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),
|
||||
EmailConfirmed = table.Column<bool>(nullable: false),
|
||||
PasswordHash = table.Column<string>(nullable: true),
|
||||
SecurityStamp = table.Column<string>(nullable: true),
|
||||
ConcurrencyStamp = table.Column<string>(nullable: true),
|
||||
PhoneNumber = table.Column<string>(nullable: true),
|
||||
PhoneNumberConfirmed = table.Column<bool>(nullable: false),
|
||||
TwoFactorEnabled = table.Column<bool>(nullable: false),
|
||||
LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
|
||||
LockoutEnabled = table.Column<bool>(nullable: false),
|
||||
AccessFailedCount = table.Column<int>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetRoleClaims",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
|
||||
RoleId = table.Column<string>(nullable: false),
|
||||
ClaimType = table.Column<string>(nullable: true),
|
||||
ClaimValue = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
|
||||
column: x => x.RoleId,
|
||||
principalTable: "AspNetRoles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserClaims",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(nullable: false)
|
||||
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
|
||||
UserId = table.Column<string>(nullable: false),
|
||||
ClaimType = table.Column<string>(nullable: true),
|
||||
ClaimValue = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserLogins",
|
||||
columns: table => new
|
||||
{
|
||||
LoginProvider = table.Column<string>(maxLength: 128, nullable: false),
|
||||
ProviderKey = table.Column<string>(maxLength: 128, nullable: false),
|
||||
ProviderDisplayName = table.Column<string>(nullable: true),
|
||||
UserId = table.Column<string>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserRoles",
|
||||
columns: table => new
|
||||
{
|
||||
UserId = table.Column<string>(nullable: false),
|
||||
RoleId = table.Column<string>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
|
||||
column: x => x.RoleId,
|
||||
principalTable: "AspNetRoles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserTokens",
|
||||
columns: table => new
|
||||
{
|
||||
UserId = table.Column<string>(nullable: false),
|
||||
LoginProvider = table.Column<string>(maxLength: 128, nullable: false),
|
||||
Name = table.Column<string>(maxLength: 128, nullable: false),
|
||||
Value = table.Column<string>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetRoleClaims_RoleId",
|
||||
table: "AspNetRoleClaims",
|
||||
column: "RoleId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "RoleNameIndex",
|
||||
table: "AspNetRoles",
|
||||
column: "NormalizedName",
|
||||
unique: true,
|
||||
filter: "[NormalizedName] IS NOT NULL");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetUserClaims_UserId",
|
||||
table: "AspNetUserClaims",
|
||||
column: "UserId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetUserLogins_UserId",
|
||||
table: "AspNetUserLogins",
|
||||
column: "UserId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetUserRoles_RoleId",
|
||||
table: "AspNetUserRoles",
|
||||
column: "RoleId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "EmailIndex",
|
||||
table: "AspNetUsers",
|
||||
column: "NormalizedEmail");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "UserNameIndex",
|
||||
table: "AspNetUsers",
|
||||
column: "NormalizedUserName",
|
||||
unique: true,
|
||||
filter: "[NormalizedUserName] IS NOT NULL");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetRoleClaims");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetUserClaims");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetUserLogins");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetUserRoles");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetUserTokens");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetRoles");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetUsers");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,275 @@
|
|||
// <auto-generated />
|
||||
using System;
|
||||
using BlazorWasm_CSharp.Server.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
namespace BlazorWasm_CSharp.Server.Data.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
partial class ApplicationDbContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "3.0.0")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128)
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(256)")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasColumnType("nvarchar(256)")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasName("RoleNameIndex")
|
||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
||||
|
||||
b.ToTable("AspNetRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasColumnType("nvarchar(256)")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("datetimeoffset");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasColumnType("nvarchar(256)")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasColumnType("nvarchar(256)")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasColumnType("nvarchar(256)")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasName("UserNameIndex")
|
||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
||||
|
||||
b.ToTable("AspNetUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("nvarchar(128)")
|
||||
.HasMaxLength(128);
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("nvarchar(128)")
|
||||
.HasMaxLength(128);
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("nvarchar(128)")
|
||||
.HasMaxLength(128);
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(128)")
|
||||
.HasMaxLength(128);
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,53 @@
|
|||
using Microsoft.AspNetCore.Builder;
|
||||
#if (IndividualLocalAuth)
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Identity.UI;
|
||||
#endif
|
||||
#if (RequiresHttps)
|
||||
using Microsoft.AspNetCore.HttpsPolicy;
|
||||
#endif
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.ResponseCompression;
|
||||
#if (IndividualLocalAuth)
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
#endif
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System.Linq;
|
||||
#if (IndividualLocalAuth)
|
||||
using BlazorWasm_CSharp.Server.Data;
|
||||
#endif
|
||||
|
||||
namespace BlazorWasm_CSharp.Server
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
#if (IndividualLocalAuth)
|
||||
services.AddDbContext<ApplicationDbContext>(options =>
|
||||
#if (UseLocalDB)
|
||||
options.UseSqlServer(
|
||||
Configuration.GetConnectionString("DefaultConnection")));
|
||||
#else
|
||||
options.UseSqlite(
|
||||
Configuration.GetConnectionString("DefaultConnection")));
|
||||
#endif
|
||||
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
|
||||
.AddEntityFrameworkStores<ApplicationDbContext>();
|
||||
|
||||
#endif
|
||||
services.AddMvc();
|
||||
services.AddResponseCompression(opts =>
|
||||
{
|
||||
|
|
@ -29,17 +64,41 @@ namespace BlazorWasm_CSharp.Server
|
|||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
#if (IndividualLocalAuth)
|
||||
app.UseDatabaseErrorPage();
|
||||
#endif
|
||||
app.UseBlazorDebugging();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/Error");
|
||||
#if (RequiresHttps)
|
||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
#else
|
||||
}
|
||||
|
||||
#endif
|
||||
app.UseStaticFiles();
|
||||
app.UseClientSideBlazorFiles<Client.Startup>();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
#if (IndividualLocalAuth)
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
#endif
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
#if (IndividualLocalAuth)
|
||||
endpoints.MapRazorPages();
|
||||
#endif
|
||||
endpoints.MapControllers();
|
||||
|
||||
endpoints.MapFallbackToClientSideBlazor<Client.Startup>("index.html");
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
////#if (IndividualLocalAuth)
|
||||
// "ConnectionStrings": {
|
||||
////#if (UseLocalDB)
|
||||
// "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-BlazorServerWeb-CSharp-53bc9b9d-9d6a-45d4-8429-2a2761773502;Trusted_Connection=True;MultipleActiveResultSets=true"
|
||||
////#else
|
||||
// "DefaultConnection": "DataSource=app.db"
|
||||
////#endif
|
||||
// },
|
||||
////#endif
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
namespace BlazorWasm_CSharp.Shared.Authorization
|
||||
{
|
||||
public class ClaimValue
|
||||
{
|
||||
public ClaimValue()
|
||||
{
|
||||
}
|
||||
|
||||
public ClaimValue(string type, string value)
|
||||
{
|
||||
Type = type;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public string Type { get; set; }
|
||||
public string Value { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace BlazorWasm_CSharp.Shared.Authorization
|
||||
{
|
||||
public class UserInfo
|
||||
{
|
||||
public static readonly UserInfo Anonymous = new UserInfo();
|
||||
|
||||
public bool IsAuthenticated { get; set; }
|
||||
|
||||
public string NameClaimType { get; set; }
|
||||
|
||||
public string RoleClaimType { get; set; }
|
||||
|
||||
public ICollection<ClaimValue> Claims { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
|
|
@ -90,7 +91,64 @@ namespace Templates.Test
|
|||
}
|
||||
}
|
||||
|
||||
protected async Task BuildAndRunTest(string appName, Project project)
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public async Task BlazorWasmHostedTemplate_IndividualAuth_Works(bool useLocalDb)
|
||||
{
|
||||
var project = await ProjectFactory.GetOrCreateProject("blazorhostedindividual" + (useLocalDb ? "uld" : ""), Output);
|
||||
|
||||
var createResult = await project.RunDotNetNewAsync("blazorwasm", args: new[] { "--hosted", "-au", "Individual", useLocalDb ? "-uld" : "" });
|
||||
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));
|
||||
|
||||
var serverProject = GetSubProject(project, "Server", $"{project.ProjectName}.Server");
|
||||
|
||||
var serverProjectFileContents = ReadFile(serverProject.TemplateOutputDir, $"{serverProject.ProjectName}.csproj");
|
||||
if (!useLocalDb)
|
||||
{
|
||||
Assert.Contains(".db", serverProjectFileContents);
|
||||
}
|
||||
var publishResult = await serverProject.RunDotNetPublishAsync();
|
||||
Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", serverProject, publishResult));
|
||||
|
||||
// Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
|
||||
// The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build
|
||||
// later, while the opposite is not true.
|
||||
|
||||
var buildResult = await serverProject.RunDotNetBuildAsync();
|
||||
Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", serverProject, buildResult));
|
||||
|
||||
var migrationsResult = await serverProject.RunDotNetEfCreateMigrationAsync("blazorwasm");
|
||||
Assert.True(0 == migrationsResult.ExitCode, ErrorMessages.GetFailedProcessMessage("run EF migrations", serverProject, migrationsResult));
|
||||
serverProject.AssertEmptyMigration("blazorwasm");
|
||||
|
||||
if (useLocalDb)
|
||||
{
|
||||
using var dbUpdateResult = await serverProject.RunDotNetEfUpdateDatabaseAsync();
|
||||
Assert.True(0 == dbUpdateResult.ExitCode, ErrorMessages.GetFailedProcessMessage("update database", serverProject, dbUpdateResult));
|
||||
}
|
||||
|
||||
await BuildAndRunTest(project.ProjectName, serverProject, usesAuth: true);
|
||||
|
||||
using var aspNetProcess = serverProject.StartPublishedProjectAsync();
|
||||
|
||||
Assert.False(
|
||||
aspNetProcess.Process.HasExited,
|
||||
ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", serverProject, aspNetProcess.Process));
|
||||
|
||||
await aspNetProcess.AssertStatusCode("/", HttpStatusCode.OK, "text/html");
|
||||
if (BrowserFixture.IsHostAutomationSupported())
|
||||
{
|
||||
aspNetProcess.VisitInBrowser(Browser);
|
||||
TestBasicNavigation(project.ProjectName, usesAuth: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
BrowserFixture.EnforceSupportedConfigurations();
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task BuildAndRunTest(string appName, Project project, bool usesAuth = false)
|
||||
{
|
||||
using var aspNetProcess = project.StartBuiltProjectAsync();
|
||||
|
||||
|
|
@ -102,7 +160,7 @@ namespace Templates.Test
|
|||
if (BrowserFixture.IsHostAutomationSupported())
|
||||
{
|
||||
aspNetProcess.VisitInBrowser(Browser);
|
||||
TestBasicNavigation(appName);
|
||||
TestBasicNavigation(appName, usesAuth);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -110,7 +168,7 @@ namespace Templates.Test
|
|||
}
|
||||
}
|
||||
|
||||
private void TestBasicNavigation(string appName)
|
||||
private void TestBasicNavigation(string appName, bool usesAuth = false)
|
||||
{
|
||||
// Give components.server enough time to load so that it can replace
|
||||
// the prerendered content before we start making assertions.
|
||||
|
|
@ -133,6 +191,40 @@ namespace Templates.Test
|
|||
Browser.FindElement(By.CssSelector("p+button")).Click();
|
||||
Browser.Equal("Current count: 1", () => Browser.FindElement(By.CssSelector("h1 + p")).Text);
|
||||
|
||||
if (usesAuth)
|
||||
{
|
||||
Browser.FindElement(By.PartialLinkText("Log in")).Click();
|
||||
Browser.Contains("/Identity/Account/Login", () => Browser.Url);
|
||||
|
||||
Browser.FindElement(By.PartialLinkText("Register as a new user")).Click();
|
||||
|
||||
var userName = $"{Guid.NewGuid()}@example.com";
|
||||
var password = $"!Test.Password1$";
|
||||
Browser.Exists(By.Name("Input.Email"));
|
||||
Browser.FindElement(By.Name("Input.Email")).SendKeys(userName);
|
||||
Browser.FindElement(By.Name("Input.Password")).SendKeys(password);
|
||||
Browser.FindElement(By.Name("Input.ConfirmPassword")).SendKeys(password);
|
||||
Browser.FindElement(By.Id("registerSubmit")).Click();
|
||||
|
||||
// We will be redirected to the RegisterConfirmation
|
||||
Browser.Contains("/Identity/Account/RegisterConfirmation", () => Browser.Url);
|
||||
Browser.FindElement(By.PartialLinkText("Click here to confirm your account")).Click();
|
||||
|
||||
// We will be redirected to the ConfirmEmail
|
||||
Browser.Contains("/Identity/Account/ConfirmEmail", () => Browser.Url);
|
||||
|
||||
// Now we can login
|
||||
Browser.FindElement(By.PartialLinkText("Login")).Click();
|
||||
Browser.Exists(By.Name("Input.Email"));
|
||||
Browser.FindElement(By.Name("Input.Email")).SendKeys(userName);
|
||||
Browser.FindElement(By.Name("Input.Password")).SendKeys(password);
|
||||
Browser.FindElement(By.Id("login-submit")).Click();
|
||||
|
||||
// Need to navigate to fetch page
|
||||
Browser.Navigate().GoToUrl(new Uri(Browser.Url).GetLeftPart(UriPartial.Authority));
|
||||
Browser.Equal(appName.Trim(), () => Browser.Title.Trim());
|
||||
}
|
||||
|
||||
// Can navigate to the 'fetch data' page
|
||||
Browser.FindElement(By.PartialLinkText("Fetch data")).Click();
|
||||
Browser.Contains("fetchdata", () => Browser.Url);
|
||||
|
|
@ -143,6 +235,15 @@ namespace Templates.Test
|
|||
Browser.Equal(5, () => Browser.FindElements(By.CssSelector("p+table>tbody>tr")).Count);
|
||||
}
|
||||
|
||||
private string ReadFile(string basePath, string path)
|
||||
{
|
||||
var fullPath = Path.Combine(basePath, path);
|
||||
var doesExist = File.Exists(fullPath);
|
||||
|
||||
Assert.True(doesExist, $"Expected file to exist, but it doesn't: {path}");
|
||||
return File.ReadAllText(Path.Combine(basePath, path));
|
||||
}
|
||||
|
||||
private Project GetSubProject(Project project, string projectDirectory, string projectName)
|
||||
{
|
||||
var subProjectDirectory = Path.Combine(project.TemplateOutputDir, projectDirectory);
|
||||
|
|
|
|||
Loading…
Reference in New Issue