Skip to content

Commit

Permalink
Rework sample app
Browse files Browse the repository at this point in the history
  • Loading branch information
YuriyDurov committed Oct 17, 2024
1 parent 3c772cf commit a17e384
Show file tree
Hide file tree
Showing 16 changed files with 46 additions and 141 deletions.
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[*.{cs,vb}]

# IDE0130: Namespace does not match folder structure
dotnet_diagnostic.IDE0130.severity = none
5 changes: 5 additions & 0 deletions BitzArt.Blazor.Auth.sln
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{
.github\workflows\Tests.yml = .github\workflows\Tests.yml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sln", "sln", "{5A14673C-C4B6-4561-8F93-9577E4A046C8}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@inject NavigationManager NavigationManager

@code {

[Parameter, EditorRequired] public required string To { get; set; }

protected override void OnInitialized()
{
NavigationManager.NavigateTo(To);
}
}

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Found Context="routeData">
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)">
<NotAuthorized>
<RedirectToSignIn />
<Redirect To="/auth" />
</NotAuthorized>
</AuthorizeRouteView>
<FocusOnNavigate RouteData="routeData" Selector="h1" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@

public class SignInPayload
{
public string MyData { get; set; } = "Some data";
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@

public class SignUpPayload
{
public string MyData { get; set; } = "Some data";
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
@page "/auth"
@inherits PageBase

@inject NavigationManager NavigationManager
@inject IUserService UserService

<PageTitle>Sign In</PageTitle>

<h1>Sign In</h1>
<PageTitle>Auth Page | Blazor.Auth</PageTitle>

<div>
<div>
<div style="margin-top:2rem;">
<button type="submit" class="btn btn-lg btn-primary" @onclick="SignInAsync">Sign In</button>
</div>
<div>
<div style="margin-top:2rem;">
<button type="submit" class="btn btn-lg btn-primary" @onclick="SignUpAsync">Sign Up</button>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
@page "/auth-required"
@inherits PageBase
@attribute [Authorize]

@using System.Text.Json

<PageTitle>Auth Required</PageTitle>
<PageTitle>Auth Required Page | Blazor.Auth</PageTitle>

<h1>Auth Required</h1>

<AuthorizeView>
<pre>
@JsonSerializer.Serialize(@context
.User.Claims.Select(x => new
{ x.Type, x.Value, x.Issuer, x.Subject?.Name, x.ValueType }
), new JsonSerializerOptions { WriteIndented = true })
</pre>
</AuthorizeView>
You are authorized!

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
@page "/"
@inherits PageBase

<PageTitle>Home</PageTitle>
<PageTitle>Home Page | Blazor.Auth</PageTitle>

<h2>Count: @count</h2>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,12 @@
@page "/sign-out"
@inherits PageBase

@inject NavigationManager NavigationManager
@inject IUserService UserService

<PageTitle>Sign Out</PageTitle>

<h1>Sign Out</h1>

<div>
<div>
<button type="submit" class="btn btn-lg btn-primary" @onclick="SignOutAsync">Sign Out</button>
</div>
</div>


@code {
private async Task SignOutAsync()
protected override async Task OnInitializedAsync()
{
await UserService.SignOutAsync();

NavigationManager.NavigateTo("/", true);
}
}
12 changes: 9 additions & 3 deletions sample/SampleBlazorApp/SampleBlazorApp.Client/Program.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
using BitzArt.Blazor.Auth;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
internal class Program
{
private static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);

builder.AddBlazorAuth();
builder.AddBlazorAuth();

await builder.Build().RunAsync();
await builder.Build().RunAsync();
}
}
71 changes: 7 additions & 64 deletions sample/SampleBlazorApp/SampleBlazorApp/Services/JwtService.cs
Original file line number Diff line number Diff line change
@@ -1,68 +1,21 @@
using BitzArt.Blazor.Auth;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;

namespace SampleBlazorApp.Services;

public class JwtService
{
private readonly JwtSecurityTokenHandler _tokenHandler;
private readonly SigningCredentials _signingCredentials;
private readonly TimeSpan _accessTokenDuration;
private readonly TimeSpan _refreshTokenDuration;

public JwtService()
{
var options = new JwtOptions
{
PublicKey = "MIIBCgKCAQEA12zIJKpaIuNNk2yAdQ4e/EsT7al1hozyi/qFeTduf7BJFS4niFK7k9OL4VJFoUbpDt18y7Yqlz0nsEyinu/7wZJjf646yYymA8jBib/4kxQw6zH7C3qaam283k72pxb+aZOeJ6iU9KNkwTbfMHxKuTHoxySS6VH0vt3Sn0FYWryp8BVdPFlbuJp6K5otksTbdFOPgzgvwNreoI3TgA0e2clRKaEv+FGwhmY6WqR/hp/ebo0mflL2hPwJI1PLzjXdlx1sPHmYYfDTA02eJWkGYVti4oUZ9UTI5pZeRMNItSu1IyjHi45iLDQ+kRaPsx2bL/YZ7NXJu/g+dk7Lb4KdfQIDAQAB",
PrivateKey = "MIIEogIBAAKCAQEA12zIJKpaIuNNk2yAdQ4e/EsT7al1hozyi/qFeTduf7BJFS4niFK7k9OL4VJFoUbpDt18y7Yqlz0nsEyinu/7wZJjf646yYymA8jBib/4kxQw6zH7C3qaam283k72pxb+aZOeJ6iU9KNkwTbfMHxKuTHoxySS6VH0vt3Sn0FYWryp8BVdPFlbuJp6K5otksTbdFOPgzgvwNreoI3TgA0e2clRKaEv+FGwhmY6WqR/hp/ebo0mflL2hPwJI1PLzjXdlx1sPHmYYfDTA02eJWkGYVti4oUZ9UTI5pZeRMNItSu1IyjHi45iLDQ+kRaPsx2bL/YZ7NXJu/g+dk7Lb4KdfQIDAQABAoIBAE6nMQvyBqbmRtSksOIMHdQPtV74mChgHc5t0X3Id1e3jXdmOpjTXBlFC7VgzHtt4HnE9GOMR1Cgy3TbBiTxigHK6PkdK+maqKKJEeCxbpiErrewr/Ao+2gQWPzx56xqAMmbVAs2yevoHElPN34EY2PqjQrol5sIiUuGwffTa+b0f5fuhPuqsvjBRcHhZX8aCCpqrvoblwVVjWKZKsFv7oWH3+KMdm9iwmuuDdOqq51TNgqaJTSpdTl+luHq8bv7hjkx3omF8R8/JHIc2UTP5a6FA0wO77448WriyIjsUpAN4fROBVOS4a4tuHy8lEQr3udxQ1KWFj3sLBy7ls3+FiECgYEA4ZY5sJ2KmZ6xG/gwI96Skd6sc7jA+XZyo3gGeVHyh7yhooZ4JndyJZtjZ4kdiuRyuxrHOG7ZQo07DFJDDbjgRPqIcyiwbLTVkvV+FE7hPwhhN2OR2TUd4D7w9oY8eZ+C0ABXJwT2breS5XCcehAGgK+A31V3rLY4BdhIoOdNOOMCgYEA9HfVt0uz+6qZW22f4XihehELEBlwGJS8bDMoSjuDRHYDwxFErBVb+KlF0w6MLy1bv6Netdcr4aQtVzHDPpDI3MbG3/aNOq8+TXppIvDhMZTycoYzk3YGC8qbhppFH7/O4CX8Z5dd80Xni9sCVU7ePSFdk5BVi6XHTamq46WDfh8CgYAtWZz5Y4J0hZGHVOqgm2MNzh0PGoo43FYJhNyQUSgXn5VC7hODcCnTY5ylOMxmmqxx7t0z/BzTIz9Gp9bxEESNuWvq8rgc8nGpHI8fGAhyOoYIs4yjhOkfpqecd7n6nVWX6SmcH4RHF8KBO5VJeKVGA4I945mub+dtTWC0cCt3DwKBgAXplAif0xWGFblpWFGKqlUabmsQQm7FwhzXy+SntdAFDqg8Fa4XwiasaVzmYCuP7EUhPVwmfRAy+Um/kVpFBCaaxBqMivPdYyNaj4phywB4+rgcWMj7NMA6QTKrLnrLF8TCBm228nW8vhHa1R6dDrDpyqqT9g2vj7doIBLrYNe/AoGAObf5KfkjrpBBO5n//H1thZzR05g5U/hKDbwhCIzhVqP2RgJxtYkadsA3XA29RXOCD58MRsYH6nYpEw52JyP3tTp6jGSCxOM9ltYji2MEpd82yT3lOsVwJXwDL8uFFQNW2VV2xfFV41mk+5B2VqPjPZa7ewFUKluSkXy1oN8Wg1w=",
AccessTokenDuration = new TimeSpan(0, 1, 0),
RefreshTokenDuration = new TimeSpan(0, 2, 0)
};

_tokenHandler = new JwtSecurityTokenHandler();

var privateRsa = RSA.Create();
var privateKey = Convert.FromBase64String(options.PrivateKey!);
privateRsa.ImportRSAPrivateKey(privateKey, out _);

var privateSecurityKey = new RsaSecurityKey(privateRsa);

_signingCredentials = new SigningCredentials(privateSecurityKey, SecurityAlgorithms.RsaSha256);

_accessTokenDuration = options.AccessTokenDuration;
_refreshTokenDuration = options.RefreshTokenDuration;
}
private static readonly TimeSpan _accessTokenDuration = new(0, 1, 0);
private static readonly TimeSpan _refreshTokenDuration = new(1, 0, 0);

public JwtPair BuildJwtPair()
{
var issuedAt = DateTime.UtcNow;
var accessTokenExpiresAt = issuedAt + _accessTokenDuration;

var accessToken = _tokenHandler.WriteToken(new JwtSecurityToken(
claims: new[]
{
new Claim("tt", "a")
},
notBefore: issuedAt,
expires: accessTokenExpiresAt,
signingCredentials: _signingCredentials
));
var now = DateTime.UtcNow;

var refreshTokenExpiresAt = issuedAt + _refreshTokenDuration;
var accessToken = "AccessToken";
var accessTokenExpiresAt = now + _accessTokenDuration;

var refreshToken = _tokenHandler.WriteToken(new JwtSecurityToken(
claims: new[]
{
new Claim("tt", "r")
},
notBefore: issuedAt,
expires: refreshTokenExpiresAt,
signingCredentials: _signingCredentials
));
var refreshToken = "RefreshToken";
var refreshTokenExpiresAt = now + _refreshTokenDuration;

return new JwtPair
{
Expand All @@ -72,14 +25,4 @@ public JwtPair BuildJwtPair()
RefreshTokenExpiresAt = refreshTokenExpiresAt
};
}
}

internal class JwtException(string errorMessage, Exception? innerException = null) : Exception(errorMessage, innerException);

internal class JwtOptions
{
public required string PublicKey { get; set; }
public required string PrivateKey { get; set; }
public TimeSpan AccessTokenDuration { get; set; }
public TimeSpan RefreshTokenDuration { get; set; }
}

0 comments on commit a17e384

Please sign in to comment.