完成登录登出、角色列表简单展示

This commit is contained in:
wangyu 2023-11-14 23:29:21 +08:00
parent 463315de51
commit b9282ea420
19 changed files with 502 additions and 85 deletions

View File

@ -3,30 +3,46 @@ using Masa.Blazor;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Sinet.Universal.Admin.Client.Services; using Sinet.Universal.Admin.Client.Services;
using Sinet.Universal.Admin.RCL; using Sinet.Universal.Admin.RCL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Autofac; using Volo.Abp.Autofac;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using System.Reflection;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using Volo.Abp.Http.Client;
using Sinet.Universal.Admin.RCL.Global;
namespace Sinet.Universal.Admin.Client namespace Sinet.Universal.Admin.Client
{ {
[DependsOn( [DependsOn(
typeof(AdminHttpApiClientModule), typeof(AdminHttpApiClientModule),
typeof(AdminBlazorServerModule), typeof(AdminBlazorServerModule),
typeof(AbpAutofacModule))] typeof(AbpAutofacModule))]
public class ClientModule : AbpModule public class ClientModule : AbpModule
{ {
public override void PreConfigureServices(ServiceConfigurationContext context) public override void PreConfigureServices(ServiceConfigurationContext context)
{ {
PreConfigure<AbpHttpClientBuilderOptions>(options =>
{
options.ProxyClientActions.Add((remoteServiceName, context, client) =>
{
//var appService = context.GetRequiredService<IAppService>();
//var accessToken = appService.AccessToken;
if (!string.IsNullOrEmpty(GlobalVariableData.AccessToken))
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", GlobalVariableData.AccessToken);
}
});
});
} }
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.AddSingleton<MainWindow>(); var config = context.Services.GetConfiguration();
context.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(config["RemoteServices:Default:BaseUrl"]) });
context.Services.AddSingleton<MainWindow>();
context.Services.AddMasaBlazor(options => context.Services.AddMasaBlazor(options =>
{ {
options.Defaults = new Dictionary<string, IDictionary<string, object?>?>() options.Defaults = new Dictionary<string, IDictionary<string, object?>?>()
@ -41,6 +57,9 @@ namespace Sinet.Universal.Admin.Client
}; };
}); });
var basePath = Path.GetDirectoryName(Assembly.GetAssembly(typeof(AdminBlazorServerModule)).Location) ?? throw new Exception("Get the assembly root directory exception!");
context.Services.AddNav(Path.Combine(basePath, $"wwwroot/nav/nav.json"));
context.Services.AddWpfBlazorWebView(); context.Services.AddWpfBlazorWebView();
#if DEBUG #if DEBUG
context.Services.AddBlazorWebViewDeveloperTools(); context.Services.AddBlazorWebViewDeveloperTools();

View File

@ -5,8 +5,8 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:rcl="clr-namespace:Sinet.Universal.Admin.RCL;assembly=Sinet.Universal.Admin.RCL" xmlns:rcl="clr-namespace:Sinet.Universal.Admin.RCL;assembly=Sinet.Universal.Admin.RCL"
xmlns:blazor="clr-namespace:Microsoft.AspNetCore.Components.WebView.Wpf;assembly=Microsoft.AspNetCore.Components.WebView.Wpf" xmlns:blazor="clr-namespace:Microsoft.AspNetCore.Components.WebView.Wpf;assembly=Microsoft.AspNetCore.Components.WebView.Wpf"
mc:Ignorable="d" mc:Ignorable="d" WindowStartupLocation="CenterScreen"
Title="MainWindow" Height="900" Width="1400"> Title="Sinet.Universal.Admin" Height="900" Width="1400">
<Grid> <Grid>
<blazor:BlazorWebView HostPage="wwwroot\index.html" Services="{DynamicResource services}"> <blazor:BlazorWebView HostPage="wwwroot\index.html" Services="{DynamicResource services}">
<blazor:BlazorWebView.RootComponents> <blazor:BlazorWebView.RootComponents>

View File

@ -1,17 +1,78 @@
using Sinet.Universal.Admin.RCL; using Microsoft.AspNetCore.Components;
using Sinet.Universal.Admin.RCL;
using Sinet.Universal.Admin.RCL.Global;
using Sinet.Universal.Admin.RCL.Services; using Sinet.Universal.Admin.RCL.Services;
using System; using System.IdentityModel.Tokens.Jwt;
using System.Collections.Generic; using System.Net.Http;
using System.Linq; using System.Security.Claims;
using System.Text; using System.Text.Json;
using System.Threading.Tasks; using Volo.Abp.Users;
namespace Sinet.Universal.Admin.Client.Services namespace Sinet.Universal.Admin.Client.Services
{ {
public class ClientAppService : BaseAppService public class ClientAppService : BaseAppService
{ {
public ClientAppService(CustomAuthenticationStateProvider authenticationStateProvider) : base(authenticationStateProvider) private readonly HttpClient _httpClient;
private readonly CookieStorage _cookieStorage;
public ClientAppService(CustomAuthenticationStateProvider authenticationStateProvider, NavigationManager navigationManager
, CookieStorage cookieStorage
, HttpClient httpClient
) : base(authenticationStateProvider, navigationManager)
{ {
_httpClient = httpClient;
_cookieStorage = cookieStorage;
} }
public override async Task AuthenticateUserAsync(ICurrentUser user)
{
GlobalVariableData.AccessToken = await _cookieStorage.GetAsync("token");
if(!string.IsNullOrEmpty(GlobalVariableData.AccessToken))
{
var tokenInfo = new JwtSecurityToken(GlobalVariableData.AccessToken);
var claims = new List<Claim>
{
new Claim(ClaimTypes.Sid, tokenInfo.Payload.FirstOrDefault(p => p.Key == "sub").Value.ToString()),
new Claim(ClaimTypes.Name, tokenInfo.Payload.FirstOrDefault(p => p.Key == "unique_name").Value.ToString() )
};
AuthenticateUser(claims);
}
}
public override async Task LoginToServer(string username, string password)
{
var getTokenContent = new FormUrlEncodedContent(new Dictionary<string, string>()
{
{"client_id", "Admin_App"},
{"grant_type", "password"},
{"username", username},
{"password", password},
{"scope", "Admin profile openid email roles offline_access"},
});
var res = _httpClient.PostAsync("connect/token", getTokenContent).Result;
if (res.IsSuccessStatusCode)
{
var resObj = res.Content.ReadAsStringAsync().Result;
var token = JsonSerializer.Deserialize<TokenInfo>(resObj);
_cookieStorage.SetAsync("token", token.AccessToken);
_navigationManager.NavigateTo("/", true);
}
else if (res.StatusCode == System.Net.HttpStatusCode.BadRequest)
{
var resObj = res.Content.ReadAsStringAsync().Result;
}
else
{
var resObj = res.Content.ReadAsStringAsync().Result?.ToString();
}
}
public override Task LogOut()
{
_cookieStorage.SetAsync("token", string.Empty);
return base.LogOut();
}
} }
} }

View File

@ -1,40 +1,59 @@
@using Sinet.Universal.Admin.RCL.Shared @using Sinet.Universal.Admin.RCL.Shared
@using System.Security.Claims
@using Volo.Abp.Security.Claims
@inherits ProComponentBase @inherits ProComponentBase
<CascadingAuthenticationState> <MErrorHandler PopupType="ErrorPopupType.Snackbar" OnHandle="OnHandle" OnAfterHandle="OnAfterHandle">
<Router AppAssembly="@typeof(App).Assembly"> <CascadingAuthenticationState>
<Found Context="routeData"> <Router AppAssembly="@typeof(App).Assembly">
<AuthorizeView> <Found Context="routeData">
<Authorized> <AuthorizeView>
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> <Authorized>
@* <FocusOnNavigate RouteData="@routeData" Selector="h1" /> *@ <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Authorized> @* <FocusOnNavigate RouteData="@routeData" Selector="h1" /> *@
<NotAuthorized> </Authorized>
<MApp> <NotAuthorized>
<div style="height:100%;margin:0;padding:0;"> <MApp>
<Sinet.Universal.Admin.RCL.Pages.Authentication.Login_v1 /> <div style="height:100%;margin:0;padding:0;">
</div> <Sinet.Universal.Admin.RCL.Pages.Authentication.Login_v1 />
</MApp> </div>
</NotAuthorized> </MApp>
</AuthorizeView> </NotAuthorized>
</Found> </AuthorizeView>
<NotFound> </Found>
<PageTitle>Not found</PageTitle> <NotFound>
<LayoutView Layout="@typeof(MainLayout)"> <PageTitle>Not found</PageTitle>
<p role="alert">Sorry, there's nothing at this address.</p> <LayoutView Layout="@typeof(MainLayout)">
</LayoutView> <p role="alert">Sorry, there's nothing at this address.</p>
</NotFound> </LayoutView>
</Router> </NotFound>
</CascadingAuthenticationState> </Router>
</CascadingAuthenticationState>
</MErrorHandler>
@code{ @code{
[Inject] [Inject]
IAppService appService { get; set;} IAppService appService { get; set; }
protected override void OnInitialized() [Inject]
public IPopupService PopupService { get; set; }
Exception _exception { get; set; }
protected override async void OnInitialized()
{ {
appService.ReAuthenticate(CurrentUser); await appService.AuthenticateUserAsync(CurrentUser);
base.OnInitialized(); base.OnInitialized();
} }
private void OnHandle(Exception exception)
{
_exception = exception;
}
private async void OnAfterHandle(Exception exception)
{
//await PopupService.EnqueueSnackbarAsync(exception);
}
} }

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sinet.Universal.Admin.RCL.Global
{
public class GlobalVariableData
{
public static string AccessToken { get; set; }
}
}

View File

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace Sinet.Universal.Admin.RCL.Global
{
public class TokenInfo
{
[JsonPropertyName("access_token")]
public string AccessToken { get; set; }
[JsonPropertyName("token_type")]
public string TokenType { get; set; }
[JsonPropertyName("expires_in")]
public int ExpiresIn { get; set; }
[JsonPropertyName("refresh_token")]
public string RefreshToken { get; set; }
[JsonPropertyName("id_token")]
public string IdToken { get; set; }
public DateTime ExpireTime
{
get
{
return GetJwtTokenInfo().ValidTo.ToLocalTime();
}
}
private JwtSecurityToken JwtTokenInfo { get; set; }
private JwtSecurityToken JwtIdTokenInfo { get; set; }
public JwtSecurityToken GetJwtTokenInfo()
{
JwtTokenInfo ??= new JwtSecurityToken(AccessToken);
return JwtTokenInfo;
}
public JwtSecurityToken GetJwtIdTokenInfo()
{
JwtIdTokenInfo ??= new JwtSecurityToken(RefreshToken);
return JwtIdTokenInfo;
}
}
}

View File

@ -10,8 +10,14 @@ namespace Sinet.Universal.Admin.RCL
{ {
public interface IAppService public interface IAppService
{ {
void ReAuthenticate(ICurrentUser user); public string AccessToken { get; set; }
Task AuthenticateUserAsync(ICurrentUser user);
void AuthenticateUser(IEnumerable<Claim> claims); void AuthenticateUser(IEnumerable<Claim> claims);
Task LoginToServer(string username, string password);
Task LogOut();
} }
} }

View File

@ -0,0 +1,145 @@
@page "/app/role/list"
@using Sinet.Universal.Admin.RCL.Data.App.User
@using Sinet.Universal.Admin.RCL.Data.App.User.Dto
@using Volo.Abp.Identity
@inherits ProComponentBase
@inject NavigationManager Nav
<MCard>
<MCardText Class="pa-6">
<h6>Filters</h6>
@* <MRow Class="mt-3">
<MCol Sm=12 Md=4>
<MSelect @bind-Value="_userPage.Role"
Color="primary"
HideDetails="@("auto")"
Clearable
Outlined
Items="@UserService.GetRoleList()"
ItemText="u => u"
ItemValue="u => u"
Label="Role">
</MSelect>
</MCol>
<MCol Sm=12 Md=4>
<MSelect @bind-Value="_userPage.Plan"
Color="primary"
HideDetails="@("auto")"
Clearable
Outlined
Items="@UserService.GetPlanList()"
ItemText="u => u"
ItemValue="u => u"
Label="Plan">
</MSelect>
</MCol>
<MCol Sm=12 Md=4>
<MSelect @bind-Value="_userPage.Status"
Color="primary"
HideDetails="@("auto")"
Clearable
Outlined
Items="@UserService.GetStatusList()"
ItemText="u => u"
ItemValue="u => u"
Label="Status">
</MSelect>
</MCol>
</MRow> *@
</MCardText>
</MCard>
<MCard Class="mt-6">
@* <MCardText Class="pa-6">
<MRow>
<MCol Md=6 Sm=12 Class="d-flex block-center">
<span class="text-btn neutral-lighten-1--text">Show:</span>
<MSelect @bind-Value="_userPage.PageSize"
Color="primary"
Style="max-width:120px;"
Dense
Class="mx-6"
HideDetails="@("auto")"
Outlined
Items="@_pageSizes"
ItemText="u => u.ToString()"
ItemValue="u => u">
</MSelect>
<span class="text-btn">entries</span>
</MCol>
<MCol Md=6 Sm=12 Class="d-flex block-center">
<MTextField @bind-Value="_userPage.Search" Color="primary" Class="rounded-2" HideDetails="@("auto")" Flat Dense Solo BackgroundColor="fill-lighten-1" Placeholder="Search">
<PrependInnerContent>
<MIcon Size=16 Class="mr-2 neutral-lighten-1--text">mdi-magnify</MIcon>
</PrependInnerContent>
</MTextField>
<MButton Color="primary" MinWidth=80 Height=32 Class="ml-6 rounded-pill" OnClick="()=>_visible=true">
Add User
</MButton>
</MCol>
</MRow>
</MCardText> *@
<MDataTable Headers="_headers" Items="RoleList" TItem="IdentityRoleDto" ItemsPerPage="10" HideDefaultFooter Class="user ml-2 table-border-none">
<HeaderColContent Context="header">
<span class="text-subtitle">@header.Text</span>
</HeaderColContent>
<ItemColContent>
@switch (context.Header.Value)
{
case nameof(IdentityRoleDto.Name):
<span>@context.Item.Name</span>
break;
case (nameof(IdentityRoleDto.IsPublic)):
<MCheckbox Class="pa-0 ma-0" Readonly @bind-Value=@context.Item.IsPublic Color="primary"></MCheckbox>
break;
case (nameof(IdentityRoleDto.IsStatic)):
<MCheckbox Class="pa-0 ma-0" Readonly Value=@context.Item.IsStatic Color="primary"></MCheckbox>
break;
case (nameof(IdentityRoleDto.IsDefault)):
<MCheckbox Class="pa-0 ma-0" Readonly Value=@context.Item.IsDefault Color="primary"></MCheckbox>
break;
case "Action":
<MMenu Right Bottom>
<ActivatorContent Context="activatorContext">
<MButton Icon @attributes="@activatorContext.Attrs">
<MIcon XSmall>fa:fas fa-ellipsis-v</MIcon>
</MButton>
</ActivatorContent>
<ChildContent>
<MList>
<MListItem OnClick="()=>NavigateToDetails(context.Item.Id)">
<MIcon Small>fa:fas fa-user-tie</MIcon>
<MListItemTitle Class="ml-2"> Details </MListItemTitle>
</MListItem>
<MListItem OnClick="()=>NavigateToEdit(context.Item.Id)">
<MIcon Small>fa:far fa-edit</MIcon>
<MListItemTitle Class="ml-2"> Edit </MListItemTitle>
</MListItem>
<MListItem OnClick="()=>{}">
<MIcon Small>fa:far fa-trash-alt</MIcon>
<MListItemTitle Class="ml-2"> Delete </MListItemTitle>
</MListItem>
</MList>
</ChildContent>
</MMenu>
break;
default:
@context.Value
break;
}
</ItemColContent>
</MDataTable>
@* <MCardText>
<div class="d-flex">
<div class="mr-auto pt-3 text-btn neutral-lighten-1--text">Showing @((_userPage.PageIndex-1)*_userPage.PageSize+1) to @(_userPage.PageIndex*_userPage.PageSize) of @_userPage.CurrentCount entries</div>
@if (_userPage.PageCount > 0)
{
<MPagination @bind-Value="_userPage.PageIndex" Color="primary" Circle Length=@_userPage.PageCount></MPagination>
}
</div>
</MCardText> *@
</MCard>
@* <Add @bind-Visible=_visible Submit="AddUserData"></Add> *@

View File

@ -0,0 +1,49 @@
using Sinet.Universal.Admin.RCL.Data.App.User;
using Sinet.Universal.Admin.RCL.Data.App.User.Dto;
using Volo.Abp.Account;
using Volo.Abp.Identity;
namespace Sinet.Universal.Admin.RCL.Pages.App.Role
{
public partial class List
{
[Inject]
public IIdentityRoleAppService IdentityRoleAppService { get; set; }
public List<IdentityRoleDto> RoleList { get; set; }
public bool? _visible;
private List<int> _pageSizes = new() { 10, 25, 50, 100 };
private readonly List<DataTableHeader<IdentityRoleDto>> _headers = new()
{
new() { Text = "RoleName", Value = nameof(IdentityRoleDto.Name), CellClass = "" },
new() { Text = "IsPublic", Value = nameof(IdentityRoleDto.IsPublic) },
new() { Text = "IsDefault", Value = nameof(IdentityRoleDto.IsDefault) },
new() { Text = "IsStatic", Value = nameof(IdentityRoleDto.IsStatic) },
new() { Text = "ACTIONS", Value = "Action", Sortable = false }
};
private readonly Dictionary<string, string> _roleIconMap = UserService.GetRoleIconMap();
protected override async Task OnInitializedAsync()
{
var roles = await IdentityRoleAppService.GetAllListAsync();
RoleList = roles.Items.ToList();
base.OnInitializedAsync();
}
private void NavigateToDetails(Guid id)
{
Nav.NavigateTo($"/app/user/view/{id}");
}
private void NavigateToEdit(Guid id)
{
Nav.NavigateTo($"/app/role/edit/{id}");
}
private void AddUserData(UserDto userData)
{
//_userPage.UserDatas.Insert(0, userData);
}
}
}

View File

@ -1,10 +1,13 @@
using Sinet.Universal.Admin.RCL.Data.App.User; using Sinet.Universal.Admin.RCL.Data.App.User;
using Sinet.Universal.Admin.RCL.Data.App.User.Dto; using Sinet.Universal.Admin.RCL.Data.App.User.Dto;
using Volo.Abp.Account;
using Volo.Abp.Identity;
namespace Sinet.Universal.Admin.RCL.Pages.App.User namespace Sinet.Universal.Admin.RCL.Pages.App.User
{ {
public partial class List public partial class List
{ {
public bool? _visible; public bool? _visible;
public UserPage _userPage = new(UserService.GetList()); public UserPage _userPage = new(UserService.GetList());
private List<int> _pageSizes = new() { 10, 25, 50, 100 }; private List<int> _pageSizes = new() { 10, 25, 50, 100 };

View File

@ -2,6 +2,7 @@
@page "/app/user/view/{Id}" @page "/app/user/view/{Id}"
@using Sinet.Universal.Admin.RCL.Data.App.User @using Sinet.Universal.Admin.RCL.Data.App.User
@using Sinet.Universal.Admin.RCL.Data.App.User.Dto @using Sinet.Universal.Admin.RCL.Data.App.User.Dto
@using Volo.Abp.Account
@inherits ProComponentBase @inherits ProComponentBase
<MRow> <MRow>
@ -235,6 +236,9 @@
[Inject] [Inject]
private NavigationManager NavigationManager { get; set; } = null!; private NavigationManager NavigationManager { get; set; } = null!;
[Inject]
private IProfileAppService ProfileAppService { get; set; }
[CascadingParameter] [CascadingParameter]
private IPageTabsProvider? PageTabsProvider { get; set; } private IPageTabsProvider? PageTabsProvider { get; set; }
@ -247,18 +251,20 @@
set { _userData = value; } set { _userData = value; }
} }
protected override void OnInitialized() protected override async void OnInitialized()
{ {
base.OnInitialized(); base.OnInitialized();
_userData = UserService.GetList().FirstOrDefault(u => u.Id == Id); _userData = UserService.GetList().FirstOrDefault(u => u.Id == Id);
if (CurrentUser != null && _userData != null) var user = await ProfileAppService.GetAsync();
if (user != null && _userData != null)
{ {
_userData.UserName = CurrentUser.Name; _userData.FullName = user.Name;
_userData.Email = CurrentUser.Email; _userData.UserName = user.Name;
_userData.Mobile = CurrentUser.PhoneNumber; _userData.Email = user.Email;
_userData.Role = CurrentUser.Roles.First(); _userData.Mobile = user.PhoneNumber;
} }
UpdateTabTitle(); UpdateTabTitle();

View File

@ -11,9 +11,6 @@ namespace Sinet.Universal.Admin.RCL.Pages.Authentication
[Inject] [Inject]
public IAppService _appService { get; set; } public IAppService _appService { get; set; }
[Inject]
public IIdentityUserAppService UserAppService { get; set; }
[Inject] [Inject]
public IPopupService PopupService { get; set; } public IPopupService PopupService { get; set; }
@ -25,21 +22,11 @@ namespace Sinet.Universal.Admin.RCL.Pages.Authentication
{ {
try try
{ {
//var users = await UserAppService.GetListAsync(new GetIdentityUsersInput());
var res = await UserAccountAppService.LoginByPass(UserName, Password); var res = await UserAccountAppService.LoginByPass(UserName, Password);
if(res == "Succeeded") if(res == "Succeeded")
{ {
var claims = new List<Claim> await _appService.LoginToServer(UserName, Password);
{
new Claim(ClaimTypes.Sid, UserName),
new Claim(ClaimTypes.Name, UserName )
};
//_appService.AuthenticateUser(claims);
await PopupService.EnqueueSnackbarAsync("登录成功,正在跳转!", AlertTypes.Success); await PopupService.EnqueueSnackbarAsync("登录成功,正在跳转!", AlertTypes.Success);
await Task.Delay(1000);
Nav.NavigateTo($"/app/redirect_login?name={UserName}&pass={Password}", true);
} }
else else
await PopupService.EnqueueSnackbarAsync("登录失败!", AlertTypes.Error); await PopupService.EnqueueSnackbarAsync("登录失败!", AlertTypes.Error);

View File

@ -1,17 +1,25 @@
using Sinet.Universal.Admin.RCL.Pages.App.User; using System.Security.Claims;
using System.Security.Claims;
using Volo.Abp.Users; using Volo.Abp.Users;
using static Volo.Abp.Identity.IdentityPermissions;
namespace Sinet.Universal.Admin.RCL.Services namespace Sinet.Universal.Admin.RCL.Services
{ {
public class BaseAppService : IAppService public class BaseAppService : IAppService
{ {
private readonly CustomAuthenticationStateProvider _authenticationStateProvider; protected readonly NavigationManager _navigationManager;
public BaseAppService(CustomAuthenticationStateProvider authenticationStateProvider) protected readonly CustomAuthenticationStateProvider _authenticationStateProvider;
public string AccessToken { get; set; }
public BaseAppService(CustomAuthenticationStateProvider authenticationStateProvider, NavigationManager navigationManager)
{ {
_authenticationStateProvider = authenticationStateProvider; _authenticationStateProvider = authenticationStateProvider;
_navigationManager = navigationManager;
}
public virtual async Task LoginToServer(string username, string password)
{
} }
public void AuthenticateUser(IEnumerable<Claim> claims) public void AuthenticateUser(IEnumerable<Claim> claims)
@ -19,7 +27,7 @@ namespace Sinet.Universal.Admin.RCL.Services
_authenticationStateProvider.AuthenticateUser(claims); _authenticationStateProvider.AuthenticateUser(claims);
} }
public void ReAuthenticate(ICurrentUser user) public virtual Task AuthenticateUserAsync(ICurrentUser user)
{ {
if(user != null && user.IsAuthenticated) if(user != null && user.IsAuthenticated)
{ {
@ -30,7 +38,14 @@ namespace Sinet.Universal.Admin.RCL.Services
}; };
AuthenticateUser(claims); AuthenticateUser(claims);
} }
return Task.CompletedTask;
} }
public virtual Task LogOut()
{
_authenticationStateProvider.Logout();
return Task.CompletedTask;
}
} }
} }

View File

@ -18,16 +18,25 @@
</MListItemTitle> </MListItemTitle>
</MListItemContent> </MListItemContent>
</MListItem> </MListItem>
<MListItem Link Href="/pages/authentication/login-v2"> <MListItem OnClick="LogOut">
<MListItemIcon Class="mr-4"> <MListItemIcon Class="mr-4">
<MIcon Size=20 Color="neutral-lighten-4">fa:fas fa-sign-in-alt</MIcon> <MIcon Size=20 Color="neutral-lighten-4">fa:fas fa-sign-in-alt</MIcon>
</MListItemIcon> </MListItemIcon>
<MListItemContent> <MListItemContent>
<MListItemTitle> <MListItemTitle>
<span class="neutral-lighten-4--text">Login v2</span> <span class="neutral-lighten-4--text">Log Out</span>
</MListItemTitle> </MListItemTitle>
</MListItemContent> </MListItemContent>
</MListItem> </MListItem>
</MList> </MList>
</ChildContent> </ChildContent>
</MMenu> </MMenu>
@code{
[Inject]
IAppService appService { get; set;}
async void LogOut(){
await appService.LogOut();
}
}

View File

@ -16,6 +16,7 @@
<PackageReference Include="Masa.Blazor" Version="1.2.2" /> <PackageReference Include="Masa.Blazor" Version="1.2.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="7.0.13" /> <PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="7.0.13" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="7.0.13" /> <PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="7.0.13" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.0.3" />
<PackageReference Include="Volo.Abp.AspNetCore.Components" Version="7.4.2" /> <PackageReference Include="Volo.Abp.AspNetCore.Components" Version="7.4.2" />
<PackageReference Include="Volo.Abp.Identity.AspNetCore" Version="7.4.2" /> <PackageReference Include="Volo.Abp.Identity.AspNetCore" Version="7.4.2" />
</ItemGroup> </ItemGroup>

View File

@ -86,27 +86,20 @@
}, },
{ {
"Id": 14, "Id": 14,
"Title": "User", "Title": "Account",
"Icon": "mdi-account-outline", "Icon": "mdi-account-outline",
"Children": [ "Children": [
{ {
"Id": 15, "Id": 15,
"Title": "List", "Title": "User",
"Icon": "mdi-circle", "Icon": "mdi-circle",
"Href": "app/user/list" "Href": "app/user/list"
}, },
{ {
"Id": 16, "Id": 16,
"Title": "View", "Title": "Role",
"Icon": "mdi-circle", "Icon": "mdi-circle",
"Href": "app/user/view", "Href": "app/role/list",
"Target": "Self"
},
{
"Id": 17,
"Title": "Edit",
"Icon": "mdi-circle",
"Href": "app/user/edit",
"Target": "Self" "Target": "Self"
} }
] ]

View File

@ -69,5 +69,13 @@ namespace Sinet.Universal.Admin
return null; return null;
} }
[HttpGet("app/logout")]
public async Task<IActionResult> SignOut(string redirect = null, CancellationToken cancellationToken = default)
{
await SignInManager.SignOutAsync();
return new RedirectResult(redirect ?? "/");
}
} }
} }

View File

@ -43,6 +43,7 @@ using Volo.Abp.UI.Navigation.Urls;
using Volo.Abp.VirtualFileSystem; using Volo.Abp.VirtualFileSystem;
using Sinet.Universal.Admin.RCL; using Sinet.Universal.Admin.RCL;
using System.Reflection; using System.Reflection;
using Sinet.Universal.Admin.Server.Host.Services;
namespace Sinet.Universal.Admin; namespace Sinet.Universal.Admin;
@ -106,6 +107,8 @@ public class AdminBlazorModule : AbpModule
var basePath = Path.GetDirectoryName(Assembly.GetAssembly(typeof(AdminBlazorServerModule)).Location) ?? throw new Exception("Get the assembly root directory exception!"); var basePath = Path.GetDirectoryName(Assembly.GetAssembly(typeof(AdminBlazorServerModule)).Location) ?? throw new Exception("Get the assembly root directory exception!");
context.Services.AddNav(Path.Combine(basePath, $"wwwroot/nav/nav.json")); context.Services.AddNav(Path.Combine(basePath, $"wwwroot/nav/nav.json"));
context.Services.AddScoped<IAppService, ServerHostAppService>();
ConfigureAuthentication(context); ConfigureAuthentication(context);
ConfigureUrls(configuration); ConfigureUrls(configuration);
ConfigureBundles(); ConfigureBundles();

View File

@ -0,0 +1,28 @@
using Microsoft.AspNetCore.Components;
using Sinet.Universal.Admin.RCL;
using Sinet.Universal.Admin.RCL.Services;
using System.Threading.Tasks;
namespace Sinet.Universal.Admin.Server.Host.Services
{
public class ServerHostAppService : BaseAppService
{
public ServerHostAppService(
CustomAuthenticationStateProvider authenticationStateProvider
, NavigationManager navigationManager) : base(authenticationStateProvider, navigationManager)
{
}
public override Task LoginToServer(string username, string password)
{
_navigationManager.NavigateTo($"/app/redirect_login?name={username}&pass={password}", true);
return Task.CompletedTask;
}
public override Task LogOut()
{
_navigationManager.NavigateTo($"/app/logout", true);
return Task.CompletedTask;
}
}
}