Browse Source

Resolved #8972: Blazor WASM: Support applications without authentication.

pull/8983/head
Halil İbrahim Kalkan 6 years ago
parent
commit
64fa32b23c
  1. 14
      framework/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/AppWithoutAuth.razor
  2. 23
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpComponentsClaimsCache.cs
  3. 13
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/BasicThemeToolbarContributor.cs
  4. 27
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor
  5. 49
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs
  6. 24
      framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpComponentBase.cs
  7. 18
      framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs

14
framework/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/AppWithoutAuth.razor

@ -0,0 +1,14 @@
@using Microsoft.Extensions.Options
@using Volo.Abp.AspNetCore.Components.Web.Theming.Routing
@inject IOptions<AbpRouterOptions> RouterOptions
<Router AppAssembly="RouterOptions.Value.AppAssembly"
AdditionalAssemblies="RouterOptions.Value.AdditionalAssemblies">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>

23
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Security/AbpComponentsClaimsCache.cs

@ -1,5 +1,6 @@
using System.Security.Claims; using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -14,21 +15,29 @@ namespace Volo.Abp.AspNetCore.Components.Web.Security
{ {
public ClaimsPrincipal Principal { get; private set; } public ClaimsPrincipal Principal { get; private set; }
[CanBeNull]
private readonly AuthenticationStateProvider _authenticationStateProvider; private readonly AuthenticationStateProvider _authenticationStateProvider;
public AbpComponentsClaimsCache(IClientScopeServiceProviderAccessor clientScopeServiceProviderAccessor) public AbpComponentsClaimsCache(
IClientScopeServiceProviderAccessor serviceProviderAccessor)
{ {
_authenticationStateProvider = clientScopeServiceProviderAccessor.ServiceProvider.GetRequiredService<AuthenticationStateProvider>(); _authenticationStateProvider = serviceProviderAccessor.ServiceProvider.GetService<AuthenticationStateProvider>();
_authenticationStateProvider.AuthenticationStateChanged += async (task) => if (_authenticationStateProvider != null)
{ {
Principal = (await task).User; _authenticationStateProvider.AuthenticationStateChanged += async (task) =>
}; {
Principal = (await task).User;
};
}
} }
public virtual async Task InitializeAsync() public virtual async Task InitializeAsync()
{ {
var authenticationState = await _authenticationStateProvider.GetAuthenticationStateAsync(); if (_authenticationStateProvider != null)
Principal = authenticationState.User; {
var authenticationState = await _authenticationStateProvider.GetAuthenticationStateAsync();
Principal = authenticationState.User;
}
} }
} }
} }

13
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/BasicThemeToolbarContributor.cs

@ -1,7 +1,10 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic; using Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic;
using Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars; using Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars;
using Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic; using Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme
{ {
@ -12,7 +15,15 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme
if (context.Toolbar.Name == StandardToolbars.Main) if (context.Toolbar.Name == StandardToolbars.Main)
{ {
context.Toolbar.Items.Add(new ToolbarItem(typeof(LanguageSwitch))); context.Toolbar.Items.Add(new ToolbarItem(typeof(LanguageSwitch)));
context.Toolbar.Items.Add(new ToolbarItem(typeof(LoginDisplay)));
//TODO: Can we find a different way to understand if authentication was configured or not?
var authenticationStateProvider = context.ServiceProvider
.GetService<AuthenticationStateProvider>();
if (authenticationStateProvider != null)
{
context.Toolbar.Items.Add(new ToolbarItem(typeof(LoginDisplay)));
}
} }
return Task.CompletedTask; return Task.CompletedTask;

27
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor

@ -1,13 +1,12 @@
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication @using Microsoft.Extensions.Localization
@using Microsoft.Extensions.Localization
@using Volo.Abp.Users @using Volo.Abp.Users
@using Volo.Abp.MultiTenancy @using Volo.Abp.MultiTenancy
@using global::Localization.Resources.AbpUi @using global::Localization.Resources.AbpUi
@inherits AbpComponentBase
@inject ICurrentUser CurrentUser @inject ICurrentUser CurrentUser
@inject ICurrentTenant CurrentTenant @inject ICurrentTenant CurrentTenant
@inject IJSRuntime JsRuntime @inject IJSRuntime JsRuntime
@inject NavigationManager Navigation @inject NavigationManager Navigation
@inject SignOutSessionStateManager SignOutManager
@inject IStringLocalizer<AbpUiResource> UiLocalizer @inject IStringLocalizer<AbpUiResource> UiLocalizer
<AuthorizeView> <AuthorizeView>
<Authorized> <Authorized>
@ -38,24 +37,4 @@
<NotAuthorized> <NotAuthorized>
<a class="nav-link" href="authentication/login">@UiLocalizer["Login"]</a> <a class="nav-link" href="authentication/login">@UiLocalizer["Login"]</a>
</NotAuthorized> </NotAuthorized>
</AuthorizeView> </AuthorizeView>
@code{
private async Task NavigateToAsync(string uri, string target = null)
{
if (target == "_blank")
{
await JsRuntime.InvokeVoidAsync("open", uri, target);
}
else
{
Navigation.NavigateTo(uri);
}
}
private async Task BeginSignOut()
{
await SignOutManager.SetSignOutState();
await NavigateToAsync("authentication/logout");
}
}

49
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/LoginDisplay.razor.cs

@ -1,8 +1,11 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Routing; using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.JSInterop;
using Volo.Abp.UI.Navigation; using Volo.Abp.UI.Navigation;
namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic
@ -11,23 +14,32 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic
{ {
[Inject] [Inject]
protected IMenuManager MenuManager { get; set; } protected IMenuManager MenuManager { get; set; }
[Inject]
protected AuthenticationStateProvider AuthenticationStateProvider { get; set; }
protected ApplicationMenu Menu { get; set; } [CanBeNull]
protected AuthenticationStateProvider AuthenticationStateProvider;
[CanBeNull]
protected SignOutSessionStateManager SignOutManager;
protected ApplicationMenu Menu { get; set; }
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
Menu = await MenuManager.GetAsync(StandardMenus.User); Menu = await MenuManager.GetAsync(StandardMenus.User);
Navigation.LocationChanged += OnLocationChanged; Navigation.LocationChanged += OnLocationChanged;
AuthenticationStateProvider.AuthenticationStateChanged += async (task) => LazyGetService(ref AuthenticationStateProvider);
LazyGetService(ref SignOutManager);
if (AuthenticationStateProvider != null)
{ {
Menu = await MenuManager.GetAsync(StandardMenus.User); AuthenticationStateProvider.AuthenticationStateChanged += async (task) =>
await InvokeAsync(StateHasChanged); {
}; Menu = await MenuManager.GetAsync(StandardMenus.User);
await InvokeAsync(StateHasChanged);
};
}
} }
protected virtual void OnLocationChanged(object sender, LocationChangedEventArgs e) protected virtual void OnLocationChanged(object sender, LocationChangedEventArgs e)
@ -39,5 +51,26 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic
{ {
Navigation.LocationChanged -= OnLocationChanged; Navigation.LocationChanged -= OnLocationChanged;
} }
private async Task NavigateToAsync(string uri, string target = null)
{
if (target == "_blank")
{
await JsRuntime.InvokeVoidAsync("open", uri, target);
}
else
{
Navigation.NavigateTo(uri);
}
}
private async Task BeginSignOut()
{
if (SignOutManager != null)
{
await SignOutManager.SetSignOutState();
await NavigateToAsync("authentication/logout");
}
}
} }
} }

24
framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpComponentBase.cs

@ -108,6 +108,18 @@ namespace Volo.Abp.AspNetCore.Components
return reference; return reference;
} }
protected TService LazyGetService<TService>(ref TService reference) => LazyGetService(typeof(TService), ref reference);
protected TRef LazyGetService<TRef>(Type serviceType, ref TRef reference)
{
if (reference == null)
{
reference = (TRef)ScopedServices.GetService(serviceType);
}
return reference;
}
protected TService LazyGetNonScopedRequiredService<TService>(ref TService reference) => LazyGetNonScopedRequiredService(typeof(TService), ref reference); protected TService LazyGetNonScopedRequiredService<TService>(ref TService reference) => LazyGetNonScopedRequiredService(typeof(TService), ref reference);
@ -120,6 +132,18 @@ namespace Volo.Abp.AspNetCore.Components
return reference; return reference;
} }
protected TService LazyGetNonScopedService<TService>(ref TService reference) => LazyGetNonScopedService(typeof(TService), ref reference);
protected TRef LazyGetNonScopedService<TRef>(Type serviceType, ref TRef reference)
{
if (reference == null)
{
reference = (TRef)NonScopedServices.GetService(serviceType);
}
return reference;
}
[Inject] [Inject]
protected IServiceProvider NonScopedServices { get; set; } protected IServiceProvider NonScopedServices { get; set; }

18
framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs

@ -1,6 +1,9 @@
using System.Threading.Tasks; using System;
using System.Threading.Tasks;
using IdentityModel.Client; using IdentityModel.Client;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication; using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client.Authentication; using Volo.Abp.Http.Client.Authentication;
using Volo.Abp.IdentityModel; using Volo.Abp.IdentityModel;
@ -8,16 +11,18 @@ using Volo.Abp.IdentityModel;
namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly
{ {
[Dependency(ReplaceServices = true)] [Dependency(ReplaceServices = true)]
public class AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator : IdentityModelRemoteServiceHttpClientAuthenticator public class AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator
: IdentityModelRemoteServiceHttpClientAuthenticator
{ {
[CanBeNull]
protected IAccessTokenProvider AccessTokenProvider { get; } protected IAccessTokenProvider AccessTokenProvider { get; }
public AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator( public AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator(
IIdentityModelAuthenticationService identityModelAuthenticationService, IIdentityModelAuthenticationService identityModelAuthenticationService,
IAccessTokenProvider accessTokenProvider) IServiceProvider serviceProvider)
: base(identityModelAuthenticationService) : base(identityModelAuthenticationService)
{ {
AccessTokenProvider = accessTokenProvider; AccessTokenProvider = serviceProvider.GetService<IAccessTokenProvider>();
} }
public override async Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) public override async Task Authenticate(RemoteServiceHttpClientAuthenticateContext context)
@ -37,6 +42,11 @@ namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly
protected virtual async Task<string> GetAccessTokenFromAccessTokenProviderOrNullAsync() protected virtual async Task<string> GetAccessTokenFromAccessTokenProviderOrNullAsync()
{ {
if (AccessTokenProvider == null)
{
return null;
}
var result = await AccessTokenProvider.RequestAccessToken(); var result = await AccessTokenProvider.RequestAccessToken();
if (result.Status != AccessTokenResultStatus.Success) if (result.Status != AccessTokenResultStatus.Success)
{ {

Loading…
Cancel
Save