Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>EqDemo.Client</RootNamespace>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components" Version="6.0.25" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.1" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components" Version="8.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.11" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.11" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
@page "/authentication/{action}"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
<RemoteAuthenticatorView Action="@Action" />

@inject NavigationManager Navigation

@code{
[Parameter] public string? Action { get; set; }

protected override void OnInitialized()
{
var returnUrl = Uri.EscapeDataString("/");
var redirectUrl = Action?.ToLower() switch
{
"login" => $"Identity/Account/Login?returnUrl={returnUrl}",
"register" => $"Identity/Account/Register?returnUrl={returnUrl}",
"logout" => "Identity/Account/LogOut",
"profile" => "Identity/Account/Manage",
_ => ""
};

if (!string.IsNullOrEmpty(redirectUrl))
{
Navigation.NavigateTo(redirectUrl, forceLoad: true);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
@page "/reports"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal
@attribute [Authorize]
@implements IAsyncDisposable

@inject IJSRuntime JSRuntime
@inject NavigationManager NavigationManager
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject IAccessTokenProviderAccessor AccessTokenProviderAccessor

<style>
.eqv-chart-panel {
Expand Down Expand Up @@ -122,13 +119,7 @@
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender) {
var result = await AccessTokenProviderAccessor.TokenProvider.RequestAccessToken();
if (result.Status == AccessTokenResultStatus.Success && result.TryGetToken(out var token)) {
await JSRuntime.InvokeVoidAsync("easyquery.blazor.startAdhocReporting", token.Value);
}
else {
await JSRuntime.InvokeVoidAsync("consloe.error", "Unable to get access token");
}
await JSRuntime.InvokeVoidAsync("easyquery.blazor.startAdhocReporting", null);
}

await base.OnAfterRenderAsync(firstRender);
Expand Down
11 changes: 4 additions & 7 deletions AspNetCore/Blazor/AdHocReporting.BlazorWasm/Client/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

using EqDemo.Client;
Expand All @@ -8,12 +8,9 @@
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddHttpClient("EqDemo.BlazorWasm.AdhocReporting.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

// Supply HttpClient instances that include access tokens when making requests to the server project
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("EqDemo.BlazorWasm.AdhocReporting.ServerAPI"));

builder.Services.AddApiAuthorization();
builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<AuthenticationStateProvider, ServerAuthenticationStateProvider>();
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.

await builder.Build().RunAsync();
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System.Net.Http.Json;
using System.Security.Claims;
using Microsoft.AspNetCore.Components.Authorization;

namespace EqDemo.Client;

public class ServerAuthenticationStateProvider : AuthenticationStateProvider
{
private readonly HttpClient _httpClient;

public ServerAuthenticationStateProvider(HttpClient httpClient)
{
_httpClient = httpClient;
}

public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
try
{
var userInfo = await _httpClient.GetFromJsonAsync<UserInfo>("api/user");
if (userInfo != null && userInfo.IsAuthenticated)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, userInfo.UserName ?? string.Empty)
};

if (userInfo.Roles != null)
{
foreach (var role in userInfo.Roles)
{
claims.Add(new Claim(ClaimTypes.Role, role));
}
}

var identity = new ClaimsIdentity(claims, "serverauth");
return new AuthenticationState(new ClaimsPrincipal(identity));
}
}
catch (Exception)
{
// Not authenticated or server unavailable
}

return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
}

public class UserInfo
{
public bool IsAuthenticated { get; set; }
public string? UserName { get; set; }
public List<string>? Roles { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,37 @@
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication

@inject NavigationManager Navigation
@inject SignOutSessionStateManager SignOutManager

<AuthorizeView>
<Authorized>
<a href="authentication/profile">Hello, @context.User.Identity?.Name!</a>
<span>Hello, @context.User.Identity?.Name!</span>
<button class="nav-link btn btn-link" @onclick="NavigateToManage">Manage</button>
<button class="nav-link btn btn-link" @onclick="BeginSignOut">Log out</button>
</Authorized>
<NotAuthorized>
<a href="authentication/register">Register</a>
<a href="authentication/login">Log in</a>
<button class="nav-link btn btn-link" @onclick="NavigateToRegister">Register</button>
<button class="nav-link btn btn-link" @onclick="NavigateToLogin">Log in</button>
</NotAuthorized>
</AuthorizeView>

@code{
private async Task BeginSignOut(MouseEventArgs args)
private void NavigateToManage()
{
await SignOutManager.SetSignOutState();
Navigation.NavigateTo("authentication/logout");
Navigation.NavigateTo("Identity/Account/Manage", forceLoad: true);
}

private void NavigateToRegister()
{
Navigation.NavigateTo("Identity/Account/Register", forceLoad: true);
}

private void NavigateToLogin()
{
Navigation.NavigateTo("Identity/Account/Login", forceLoad: true);
}

private void BeginSignOut()
{
Navigation.NavigateTo("Identity/Account/LogOut", forceLoad: true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
@code {
protected override void OnInitialized()
{
Navigation.NavigateTo($"authentication/login?returnUrl={Uri.EscapeDataString(Navigation.Uri)}");
Navigation.NavigateTo($"Identity/Account/Login?returnUrl={Uri.EscapeDataString("/" + Navigation.ToBaseRelativePath(Navigation.Uri))}", forceLoad: true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script>

<script src="_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"></script>
<script src="_framework/blazor.webassembly.js"></script>

<!-- Google Charts script -->
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Security.Claims;
using Microsoft.AspNetCore.Mvc;

namespace EqDemo.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class UserController : ControllerBase
{
[HttpGet]
public IActionResult GetCurrentUser()
{
if (User.Identity?.IsAuthenticated == true)
{
return Ok(new
{
IsAuthenticated = true,
UserName = User.Identity.Name,
Roles = User.FindAll(ClaimTypes.Role).Select(c => c.Value).ToList()
});
}

return Ok(new { IsAuthenticated = false });
}
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
using Microsoft.AspNetCore.ApiAuthorization.IdentityServer;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;

using Duende.IdentityServer.EntityFramework.Options;

using EqDemo.Models;

namespace EqDemo.Data
{
public class AppDbContext : ApiAuthorizationDbContext<ApplicationUser>
public class AppDbContext : IdentityDbContext<ApplicationUser>
{
public AppDbContext(
DbContextOptions options,
IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options, operationalStoreOptions)
DbContextOptions options) : base(options)
{
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<Nullable>disable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>EqDemo.BlazorWasm.AdhocReporting.Server</UserSecretsId>
<RootNamespace>EqDemo.Server</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="6.0.1" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="2.1.7" />
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="6.34.0" />
<PackageReference Include="NuGet.Common" Version="5.11.5" />
<PackageReference Include="NuGet.Protocol" Version="5.11.5" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.11" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.2" />
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="6.35.0" />
<PackageReference Include="NuGet.Common" Version="6.11.0" />
<PackageReference Include="NuGet.Protocol" Version="6.11.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
<PackageReference Include="System.Drawing.Common" Version="4.7.2" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.34.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.35.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
</ItemGroup>
Expand All @@ -23,14 +23,13 @@
<ProjectReference Include="..\Shared\EqDemo.BlazorWasm.AdhocReporting.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="6.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.1" />
<PackageReference Include="Microsoft.AspNetCore.ApiAuthorization.IdentityServer" Version="6.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.1" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.11" />
</ItemGroup>
<ItemGroup>
<!-- DB initialization packages. They are not necessary for EasyQuery working and can be removed in production -->
Expand All @@ -48,4 +47,4 @@
<PackageReference Include="Korzh.EasyQuery.EntityFrameworkCore.Relational" Version="7.4.0" />
<PackageReference Include="Korzh.EasyQuery.EntityFrameworkCore.Identity" Version="7.4.0" />
</ItemGroup>
</Project>
</Project>
19 changes: 4 additions & 15 deletions AspNetCore/Blazor/AdHocReporting.BlazorWasm/Server/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using System.IdentityModel.Tokens.Jwt;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;

Expand Down Expand Up @@ -29,18 +27,10 @@
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<AppDbContext>();

builder.Services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, AppDbContext>(options => {
//the following 2 lines are necessary to support roles on the WebAssembly side
options.IdentityResources["openid"].UserClaims.Add("role");
options.ApiResources.Single().UserClaims.Add("role");
});

// We need to do this as it maps "role" to ClaimTypes.Role and causes issues
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

builder.Services.AddAuthentication()
.AddIdentityServerJwt();
builder.Services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
});

//EasyQuery services
builder.Services.AddEasyQuery()
Expand Down Expand Up @@ -79,7 +69,6 @@

app.UseRouting();

app.UseIdentityServer();
app.UseAuthentication();
app.UseAuthorization();

Expand Down
Loading