Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

1 change: 1 addition & 0 deletions UltimateAuth.slnx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Solution>
<Folder Name="/Samples/">
<Project Path="samples/blazor-server/UltimateAuth.BlazorServer/UltimateAuth.BlazorServer.csproj" />
<Project Path="samples/blazor-standalone-wasm/UltimateAuth.Sample.BlazorStandaloneWasm/UltimateAuth.Sample.BlazorStandaloneWasm.csproj" Id="27bd3c4d-65a9-4c70-a6c9-4178b1897730" />
</Folder>
<Folder Name="/Solution Items/">
<File Path="Readme.md" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<script src="_framework/blazor.web.js"></script>
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
<script src="_content/CodeBeam.MudBlazor.Extensions/MudExtensions.min.js"></script>
<script src="_content/CodeBeam.UltimateAuth.Client/uauth.js"></script>
</body>

</html>
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
@inherits LayoutComponentBase

<UAuthClientProvider />

<MudThemeProvider />
<MudPopoverProvider />
<MudDialogProvider />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,47 @@
@page "/"
@inject IUAuthFlowService<UserId> FlowService
@page "/login"
@using CodeBeam.UltimateAuth.Client
@using CodeBeam.UltimateAuth.Core.Abstractions
@using CodeBeam.UltimateAuth.Core.Runtime
@using CodeBeam.UltimateAuth.Server.Abstractions
@using CodeBeam.UltimateAuth.Server.Cookies
@using CodeBeam.UltimateAuth.Server.Infrastructure
@inject IUAuthFlowService<UserId> Flow
@inject ISnackbar Snackbar
@inject IHttpClientFactory Http
@inject ISessionQueryService<UserId> SessionQuery
@inject ICredentialResolver CredentialResolver
@inject IClock Clock
@inject IUAuthCookieManager CookieManager
@inject IHttpContextAccessor HttpContextAccessor
@inject IUAuthClient UAuthClient
@inject NavigationManager Nav
@inject IUAuthProductInfoProvider ProductInfo


<div class="uauth-page d-flex align-center justify-center">
<MudStack Class="uauth-stack">
<form method="post" action="/auth/login">
<MudText Typo="Typo.h4">Welcome to UltimateAuth!</MudText>
<!-- Hidden fields -->
<input type="hidden" name="Identifier" value="@_username" />
<input type="hidden" name="Secret" value="@_password" />
<UALoginForm @ref="_form" Identifier="@_username" Secret="@_password">
<MudStack>
<MudText Typo="Typo.h4">Welcome to UltimateAuth!</MudText>
<MudTextField @bind-Value="@_username" Variant="Variant.Outlined" Label="Username" Immediate="true" />
<MudPasswordField @bind-Value="@_password" Variant="Variant.Outlined" Label="Password" Immediate="true" />
<MudButton Variant="Variant.Filled" Color="Color.Primary" ButtonType="ButtonType.Submit">Login</MudButton>
</MudStack>
</UALoginForm>

<MudStack Class="mud-width-full" Row="true">
<MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="ValidateAsync">Validate</MudButton>
<MudButton Variant="Variant.Filled" Color="Color.Secondary" OnClick="LogoutAsync">Logout</MudButton>
<MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="RefreshAsync">Refresh</MudButton>
</MudStack>

<!-- UI -->
<MudTextField @bind-Value="@_username" Variant="Variant.Outlined" Label="Username" Immediate="true" />
<MudPasswordField @bind-Value="@_password" Variant="Variant.Outlined" Label="Password" Immediate="true" />
<MudStack Class="mud-width-full">
<MudButton Variant="Variant.Filled" Color="Color.Info" OnClick="ProgrammaticLogin">Programmatic Login</MudButton>
</MudStack>

<MudButton Variant="Variant.Filled" Color="Color.Primary" ButtonType="ButtonType.Submit">Login</MudButton>
</form>
<MudStack Spacing="0">
<MudText><b>@ProductInfo.Get().ProductName</b> v @ProductInfo.Get().Version</MudText>
<MudText>Client Profile: @ProductInfo.Get().ClientProfile.ToString()</MudText>
</MudStack>
</MudStack>
</div>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using CodeBeam.UltimateAuth.Core.Contracts;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http;
using CodeBeam.UltimateAuth.Client;
using CodeBeam.UltimateAuth.Core.Contracts;
using CodeBeam.UltimateAuth.Core.Domain;
using MudBlazor;

namespace UltimateAuth.BlazorServer.Components.Pages
Expand All @@ -10,38 +10,109 @@ public partial class Home
private string? _username;
private string? _password;

private async Task LoginAsync()
private UALoginForm _form = null!;

private async Task ProgrammaticLogin()
{
var request = new LoginRequest
{
Identifier = "Admin",
Secret = "Password!",
};
await UAuthClient.LoginAsync(request);
}

private async Task ValidateAsync()
{
var httpContext = HttpContextAccessor.HttpContext;

try
if (httpContext is null)
{
//var result = await FlowService.LoginAsync(new LoginRequest
//{
// Identifier = _username!,
// Secret = _password!
//});
var client = Http.CreateClient();
var result = await client.PostAsJsonAsync(
"https://localhost:7213/auth/login",
new LoginRequest
{
Identifier = _username!,
Secret = _password!
});
Snackbar.Add("HttpContext not available", Severity.Error);
return;
}

var credential = CredentialResolver.Resolve(httpContext);

if (!result.IsSuccessStatusCode)
if (credential is null)
{
Snackbar.Add("No credential found", Severity.Error);
return;
}

if (!AuthSessionId.TryCreate(credential.Value, out var sessionId))
{
Snackbar.Add("Invalid session id", Severity.Error);
return;
}

var result = await SessionQuery.ValidateSessionAsync(
new SessionValidationContext
{
Snackbar.Add("Login failed.", Severity.Info);
return;
}
TenantId = credential.TenantId,
SessionId = sessionId,
Device = credential.Device,
Now = Clock.UtcNow
});

Snackbar.Add("Successfully logged in!", Severity.Success);
if (result.IsValid)
{
Snackbar.Add("Session is valid ✅", Severity.Success);
}
catch (Exception ex)
else
{
Snackbar.Add(ex.ToString(), Severity.Error);
Snackbar.Add(
$"Session invalid ❌ ({result.State})",
Severity.Error);
}
}

private async Task LogoutAsync()
{
await UAuthClient.LogoutAsync();
Snackbar.Add("Logged out", Severity.Success);
}

private async Task RefreshAsync()
{
await UAuthClient.RefreshAsync();
//Snackbar.Add("Logged out", Severity.Success);
}

protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
var uri = Nav.ToAbsoluteUri(Nav.Uri);
var query = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(uri.Query);

if (query.TryGetValue("error", out var error))
{
ShowLoginError(error.ToString());
ClearQueryString();
}
}
}

private void ShowLoginError(string code)
{
var message = code switch
{
"invalid" => "Invalid username or password.",
"locked" => "Your account is locked.",
"mfa" => "Multi-factor authentication required.",
_ => "Login failed."
};

Snackbar.Add(message, Severity.Error);
}

private void ClearQueryString()
{
var uri = new Uri(Nav.Uri);
var clean = uri.GetLeftPart(UriPartial.Path);
Nav.NavigateTo(clean, replace: true);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

@using CodeBeam.UltimateAuth.Core.Abstractions
@using CodeBeam.UltimateAuth.Core.Domain
@using CodeBeam.UltimateAuth.Client

@using MudBlazor
@using MudExtensions
40 changes: 31 additions & 9 deletions samples/blazor-server/UltimateAuth.BlazorServer/Program.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using CodeBeam.UltimateAuth.Client.Extensions;
using CodeBeam.UltimateAuth.Core.Extensions;
using CodeBeam.UltimateAuth.Core.Options;
using CodeBeam.UltimateAuth.Credentials.InMemory;
using CodeBeam.UltimateAuth.Security.Argon2;
using CodeBeam.UltimateAuth.Server.Extensions;
Expand All @@ -12,7 +15,11 @@

// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
.AddInteractiveServerComponents()
.AddCircuitOptions(options =>
{
options.DetailedErrors = true;
});

builder.Services.AddMudServices();
builder.Services.AddMudExtensions();
Expand All @@ -22,25 +29,40 @@

builder.Services.AddHttpContextAccessor();

builder.Services.AddUltimateAuth();

builder.Services.AddUltimateAuthServer()
builder.Services.AddUltimateAuthServer(o => {
o.Diagnostics.EnableRefreshHeaders = true;
})
.AddInMemoryCredentials()
.AddUltimateAuthInMemorySessions()
.AddUltimateAuthInMemoryTokens()
.AddUltimateAuthArgon2();

builder.Services.AddHttpClient("AuthApi", client =>
{
client.BaseAddress = new Uri("https://localhost:7213");
})
.ConfigurePrimaryHttpMessageHandler(() =>
builder.Services.AddUltimateAuthClient();

builder.Services.AddScoped(sp =>
{
return new HttpClientHandler
var navigation = sp.GetRequiredService<NavigationManager>();

return new HttpClient
{
UseCookies = true
BaseAddress = new Uri(navigation.BaseUri)
};
});

//builder.Services.AddHttpClient("AuthApi", client =>
//{
// client.BaseAddress = new Uri("https://localhost:7213");
//})
//.ConfigurePrimaryHttpMessageHandler(() =>
//{
// return new HttpClientHandler
// {
// UseCookies = true
// };
//});


var app = builder.Build();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<Version>0.0.1-preview</Version>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CodeBeam.MudBlazor.Extensions" Version="8.3.0" />
<PackageReference Include="MudBlazor" Version="8.15.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MudBlazor" Version="8.15.0" />
<PackageReference Include="CodeBeam.MudBlazor.Extensions" Version="8.3.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\CodeBeam.UltimateAuth.Client\CodeBeam.UltimateAuth.Client.csproj" />
<ProjectReference Include="..\..\..\src\CodeBeam.UltimateAuth.Core\CodeBeam.UltimateAuth.Core.csproj" />
<ProjectReference Include="..\..\..\src\CodeBeam.UltimateAuth.Server\CodeBeam.UltimateAuth.Server.csproj" />
<ProjectReference Include="..\..\..\src\security\CodeBeam.UltimateAuth.Security.Argon2\CodeBeam.UltimateAuth.Security.Argon2.csproj" />
Expand Down
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,16 @@
@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>
Loading
Loading