Blazor服务器中的页面刷新后未对登录用户进行身份验证

时间:2020-06-15 13:12:11

标签: authentication blazor

我创建了一个自定义AuthenticationStateProvider,用于将用户设置为已认证。 第一次登录时有效,但是在刷新页面时,该用户没有再次获得授权,而是被重定向到登录页面。 我在启动中设置了CookieAuthentication,但这没有帮助。

这是我的启动代码:

    public void ConfigureServices(IServiceCollection services)
        {
            try
            {




                services.AddRazorPages();
                services.AddServerSideBlazor(sb =>
                {
                    sb.DetailedErrors = true;
                });

                services.Configure<CookiePolicyOptions>(options =>
                {
                    options.CheckConsentNeeded = context => true;
                    options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
                });
                services.AddAuthentication(
                        CookieAuthenticationDefaults.AuthenticationScheme)
                    .AddCookie();

                services.AddBlazoredLocalStorage();
                services.AddScoped<IUserService, UserService>();
                //services.AddScoped<AuthenticationStateProvider, CustomAuthenticationStateProvider>();
                services.AddScoped<CustomAuthenticationStateProvider>();
                services.AddScoped<AuthenticationStateProvider>(provider => provider.GetRequiredService<CustomAuthenticationStateProvider>());
                services.AddScoped<IAppStateService, AppStateService>();



                services.AddHttpContextAccessor();
                services.AddScoped<HttpContextAccessor>();

                services.AddHttpClient();
                services.AddScoped<HttpClient>();

                services.AddScoped<SpinnerService>();
                //services.AddScoped<BlazorDisplaySpinnerAutomaticallyHttpMessageHandler>();
                //services.AddSingleton(sp =>
                //{
                //    BlazorDisplaySpinnerAutomaticallyHttpMessageHandler blazorDisplaySpinnerAutomaticallyHttpMessageHandler = sp.GetRequiredService<BlazorDisplaySpinnerAutomaticallyHttpMessageHandler>();
                //    HttpMessageHandler handler = sp.GetService<HttpMessageHandler>();
                //    blazorDisplaySpinnerAutomaticallyHttpMessageHandler.InnerHandler = handler;
                //    HttpClient client = handler != null ? new HttpClient(blazorDisplaySpinnerAutomaticallyHttpMessageHandler) : new HttpClient();
                //    var uriHelper = sp.GetRequiredService<Microsoft.AspNetCore.Components.NavigationManager>();
                //    client.BaseAddress = new Uri(uriHelper.BaseUri);
                //    return client;
                //});

                services.AddBlazorise(options =>
                        {
                            options.ChangeTextOnKeyPress = false; // optional
                    })
                        .AddBootstrapProviders()
                        .AddFontAwesomeIcons();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
        {
            try
            {


            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseHttpsRedirection();
            app.UseCookiePolicy();
            app.UseAuthentication();
            app.UseAuthorization();
            app.ApplicationServices.UseBootstrapProviders()
                                    .UseFontAwesomeIcons();
            loggerFactory.AddLog4Net();
            app.UseEndpoints(endpoints =>
                {
                    endpoints.MapBlazorHub();
                    endpoints.MapFallbackToPage("/_Host");
                });
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }

这是CustomAuthenticationStateProvider:

using Inovoo.OcrValidator.Interfaces;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Http;
using NovoValidateWeb.Services;
using System;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Linq;
using Microsoft.AspNetCore.Authentication.Cookies;
using Blazored.LocalStorage;
using System.Diagnostics;
using System.Threading;
using Microsoft.AspNetCore.Authentication;

namespace NovoValidateWeb.Data
{
    public class CustomAuthenticationStateProvider : AuthenticationStateProvider
    {
        private readonly ISessionService _sessionService;
        private readonly IAppStateService _appStateService;
        private readonly HttpContextAccessor _context;
        private User _authUser;


        public IAppStateService AppStateService
        {
            get;
            set;
        }

        public CustomAuthenticationStateProvider(IAppStateService appStateService, HttpContextAccessor context)
        {

            _context = context;
            _appStateService = appStateService;
            _sessionService = _appStateService.SessionService;


        }



        public override async Task<AuthenticationState> GetAuthenticationStateAsync()
        {

            ClaimsIdentity identity;

            if (_authUser != null)
            {
                identity = new ClaimsIdentity(new[]
                {
                    new Claim(ClaimTypes.Name, _authUser.Username),
                    new Claim("sessionid", _authUser.SessionId.ToString())
                }, CookieAuthenticationDefaults.AuthenticationScheme);
            }
            else
            {
                identity = new ClaimsIdentity();
            }

            ClaimsPrincipal user = new ClaimsPrincipal(identity);

            return await Task.FromResult(new AuthenticationState(user));
        }

        public bool MarkUserAsAuthenticated(User currentUser)
        {
            _authUser = currentUser;
            string username = currentUser.Username;

            ClaimsIdentity identity = new ClaimsIdentity(new[]
            {
                new Claim(ClaimTypes.Name, username),

            }, CookieAuthenticationDefaults.AuthenticationScheme);


            ClaimsPrincipal user = new ClaimsPrincipal(identity);


            SessionPrincipal sessionUser = new SessionPrincipal(username, x =>
            {
                return true;
            }, Guid.Empty);
            Debug.Print($"MarkUserAsAuth - Before - Session ID = {currentUser.SessionId} ");

            MarkUserAsLoggedOut(username);


            Guid sessionId = _sessionService.Login(sessionUser);
            currentUser.SessionId = sessionId;
            _appStateService.AuthenticatedUser = currentUser;
            Debug.Print($"MarkUserAsAuth - After - Session ID = {sessionId} ");

            identity.AddClaim(new Claim("sessionid", sessionId.ToString()));
            _context.HttpContext.User = user;
            _context.HttpContext.SignInAsync(
                                        CookieAuthenticationDefaults.AuthenticationScheme,
                                        user);
            _appStateService.Init();
            NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(user)));
            return true;
        }

        public void MarkUserAsLoggedOut(string username)
        {
            Logout(username);
            System.Security.Claims.ClaimsIdentity identity = new ClaimsIdentity();

            ClaimsPrincipal user = new ClaimsPrincipal(identity);
        }

        private void Logout(string username)
        {
            var session = _sessionService.GetSessionByUserName(username);
            if (session != null)
            {
                Debug.Print($"AuthProvider - Logout - Session ID = {session.SessionId} ");
                _sessionService.Logout(session.SessionId);
            }

        }
    }
}

0 个答案:

没有答案