Skip to content

Commit

Permalink
Added initial project structure
Browse files Browse the repository at this point in the history
  • Loading branch information
KristofferStrube committed Sep 24, 2023
1 parent 8a9a770 commit 4dd2d4f
Show file tree
Hide file tree
Showing 56 changed files with 7,140 additions and 0 deletions.
34 changes: 34 additions & 0 deletions Blazor.WebAuthentication.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KristofferStrube.Blazor.CredentialManagement", "src\KristofferStrube.Blazor.CredentialManagement\KristofferStrube.Blazor.CredentialManagement.csproj", "{A0B974A9-0058-4DC7-AEFD-D1A4E4AA24FA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KristofferStrube.Blazor.WebAuthentication", "src\KristofferStrube.Blazor.WebAuthentication\KristofferStrube.Blazor.WebAuthentication.csproj", "{A696790A-5532-4C70-9FE0-57892698BDAF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KristofferStrube.Blazor.WebAuthentication.BlazorExample", "samples\KristofferStrube.Blazor.WebAuthentication.BlazorExample\KristofferStrube.Blazor.WebAuthentication.BlazorExample.csproj", "{9811E16F-3101-45B3-B3AA-304A1391F0A0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A0B974A9-0058-4DC7-AEFD-D1A4E4AA24FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A0B974A9-0058-4DC7-AEFD-D1A4E4AA24FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A0B974A9-0058-4DC7-AEFD-D1A4E4AA24FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A0B974A9-0058-4DC7-AEFD-D1A4E4AA24FA}.Release|Any CPU.Build.0 = Release|Any CPU
{A696790A-5532-4C70-9FE0-57892698BDAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A696790A-5532-4C70-9FE0-57892698BDAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A696790A-5532-4C70-9FE0-57892698BDAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A696790A-5532-4C70-9FE0-57892698BDAF}.Release|Any CPU.Build.0 = Release|Any CPU
{9811E16F-3101-45B3-B3AA-304A1391F0A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9811E16F-3101-45B3-B3AA-304A1391F0A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9811E16F-3101-45B3-B3AA-304A1391F0A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9811E16F-3101-45B3-B3AA-304A1391F0A0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0-rc.1.23421.29" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0-rc.1.23421.29" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\KristofferStrube.Blazor.WebAuthentication\KristofferStrube.Blazor.WebAuthentication.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
@page "/"
@using System.Security.Cryptography;
@inject CredentialsService CredentialsService;

<PageTitle>Blazor Web Authentication</PageTitle>

<h2>Blazor Web Authentication</h2>

<p>Here you can try create a credential from your device's native identification mechanism.</p>

<button class="btn btn-success" @onclick="CreateCredential">Create Credentials</button>

<br />
<br />
@if (credential is not null)
{
<b>Type: </b> @type
<br />
<b>Id: </b> @id
<br />
<br />
<button class="btn btn-primary" @onclick="GetCredential">Request Credentials from Id</button>

@if (successfulGettingCredential is {} success)
{
<br />
<br />
<div class="rounded p-2 text-white @(success ? "bg-success": "bg-danger")">
@(success ? "You logged in and validated your credentials" : errorMessage ?? "You were not successful in logging on.")
</div>
}
}
else if (errorMessage is not null)
{
<div class="rounded p-2 text-white bg-danger">@errorMessage</div>
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
using KristofferStrube.Blazor.CredentialManagement;
using KristofferStrube.Blazor.WebIDL.Exceptions;
using Microsoft.AspNetCore.Components;
using System.Security.Cryptography;
using System.Text;

namespace KristofferStrube.Blazor.WebAuthentication.BlazorExample.Pages;

public partial class Index : ComponentBase
{
private CredentialsContainer container = default!;
private PublicKeyCredential? credential;
private PublicKeyCredential? validatedCredential;
private bool? successfulGettingCredential = null;
private string? type;
private string? id;
private string? errorMessage;

protected override async Task OnInitializedAsync()
{
container = await CredentialsService.GetCredentialsAsync();
}

private async Task CreateCredential()
{
byte[] challenge = RandomNumberGenerator.GetBytes(32);
byte[] userId = Encoding.ASCII.GetBytes("bob");
CredentialCreationOptions options = new()
{
PublicKey = new PublicKeyCredentialCreationOptions()
{
Rp = new PublicKeyCredentialRpEntity
{
Name = "Kristoffer Strube Consulting"
},
User = new PublicKeyCredentialUserEntity()
{
Name = "bob",
Id = userId,
DisplayName = "Bob"
},
Challenge = challenge,
PubKeyCredParams =
[
new PublicKeyCredentialParameters()
{
Type = PublicKeyCredentialType.PublicKey,
Alg = -257
}
],
Timeout = 360000,
}
};

try
{
credential = await container.CreateAsync(options) is { } c ? new PublicKeyCredential(c) : null;
}
catch (DOMException exception)
{
errorMessage = $"{exception.Name}: \"{exception.Message}\"";
credential = null;
}
if (credential is not null)
{
type = await credential.GetTypeAsync();
id = await credential.GetIdAsync();
}
}

private async Task GetCredential()
{
byte[] challenge = RandomNumberGenerator.GetBytes(32);
CredentialRequestOptions options = new()
{
PublicKey = new PublicKeyCredentialRequestOptions()
{
Challenge = challenge,
Timeout = 360000,
AllowCredentials = [
new PublicKeyCredentialDescriptor()
{
Type = PublicKeyCredentialType.PublicKey,
Id = await credential!.GetRawIdAsync()
}
]
}
};

try
{
validatedCredential = await container.GetAsync(options) is { } c ? new PublicKeyCredential(c) : null;
}
catch (DOMException exception)
{
errorMessage = $"{exception.Name}: \"{exception.Message}\"";
validatedCredential = null;
}

successfulGettingCredential = validatedCredential is not null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using KristofferStrube.Blazor.CredentialManagement;
using KristofferStrube.Blazor.WebAuthentication.BlazorExample;
using KristofferStrube.Blazor.WebIDL;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddCredentialsService();

WebAssemblyHost app = builder.Build();

await app.Services.SetupErrorHandlingJSInterop();

await app.RunAsync();
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"$schema": "http:https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http:https://localhost:28210",
"sslPort": 44363
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"inspectUri": "{wsProtocol}:https://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "http:https://localhost:5289",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"inspectUri": "{wsProtocol}:https://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "https://localhost:7203;http:https://localhost:5289",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"inspectUri": "{wsProtocol}:https://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@inherits LayoutComponentBase

<div class="page">
<div class="sidebar">
<NavMenu />
</div>

<main>
<div class="top-row px-4">
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>

<article class="content px-4">
@Body
</article>
</main>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}

main {
flex: 1;
}

.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}

.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}

.top-row ::deep a, .top-row ::deep .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
text-decoration: none;
}

.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
text-decoration: underline;
}

.top-row ::deep a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}

@media (max-width: 640.98px) {
.top-row:not(.auth) {
display: none;
}

.top-row.auth {
justify-content: space-between;
}

.top-row ::deep a, .top-row ::deep .btn-link {
margin-left: 0;
}
}

@media (min-width: 641px) {
.page {
flex-direction: row;
}

.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}

.top-row {
position: sticky;
top: 0;
z-index: 1;
}

.top-row.auth ::deep a:first-child {
flex: 1;
text-align: right;
width: 0;
}

.top-row, article {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}
Loading

0 comments on commit 4dd2d4f

Please sign in to comment.