【问题标题】:trouble after publishing BLAZOR website to IIS将 BLAZOR 网站发布到 IIS 后出现问题
【发布时间】:2021-11-11 06:58:06
【问题描述】:

我在主机上发布了我的项目。我的项目在本地系统上运行没有任何问题。

但是在主机上发布时,它会出错。我们主机的IIS版本是10。

而我的webconfig文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath="dotnet" arguments=".\LosacoWeb.Server.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
    </system.webServer>
  </location>
</configuration>

我附上错误图片如下:

还有错误信息:

Uncaught TypeError: Cannot read properties of undefined (reading 'register')
    at (index):17
/favicon.ico:1 Failed to load resource: the server responded with a status of 404 (Not Found)
dotnet.5.0.4.js:1 mono_wasm_runtime_ready fe00e07a-5519-4dfe-b35a-f867dbaf2e28
blazor.webassembly.js:1 System.Reflection.TargetInvocationException: Arg_TargetInvocationException
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1  ---> System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.AspNetCore.Components.Authorization, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' or one of its dependencies.
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 IO_FileName_Name, Microsoft.AspNetCore.Components.Authorization, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1    at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[<Main>d__0](<Main>d__0& stateMachine)
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1    at LosacoWeb.Client.Program.Main(String[] args)
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1    Exception_EndOfInnerExceptionStack
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1    at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
d.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1    at Microsoft.AspNetCore.Components.WebAssembly.Hosting.EntrypointInvoker.InvokeEntrypoint(String assemblyName, String[] args)

经过一段时间检查我们的代码后,我知道我们的问题出在 JWTAuthenticationStateProvider 类中。当我们发布没有该类的网站时,我们的网站运行良好。我将该类代码添加如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text.Json;
using System.Threading.Tasks;
using LosacoWeb.Client.Helpers;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.JSInterop;

namespace LosacoWeb.Client.Auth
{
    public class JWTAuthenticationStateProvider : AuthenticationStateProvider, ILoginService
    {
        private readonly IJSRuntime js;
        private readonly string TokenKey = "******";
        private readonly HttpClient httpClient;
        private AuthenticationState Anonymous =>
        new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));

        public JWTAuthenticationStateProvider(IJSRuntime js, HttpClient httpClient)
        {
            this.js = js;
            this.httpClient = httpClient;
        }


        public override async Task<AuthenticationState> GetAuthenticationStateAsync()
        {
            var token = await js.GetFromLocalStorage(TokenKey);

            if (string.IsNullOrEmpty(token))
            {
                return Anonymous;
            }

            return BuildAuthenticationState(token);
        }

        public AuthenticationState BuildAuthenticationState(string token)
        {
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);
            return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(ParseClaimsFromJwt(token), "jwt")));
        }


        private IEnumerable<Claim> ParseClaimsFromJwt(string jwt)
        {
            var claims = new List<Claim>();
            var payload = jwt.Split(".")[1];
            var jsonBytes = ParsBase64WithoutPadding(payload);
            var keyValuePairs = JsonSerializer.Deserialize<Dictionary<string, object>>(jsonBytes);

            keyValuePairs.TryGetValue(ClaimTypes.Role, out object roles);

            if (roles != null)
            {
                if (roles.ToString().Trim().StartsWith("["))
                {
                    var parsedRoles = JsonSerializer.Deserialize<string[]>(roles.ToString());
                    foreach (var parsedRole in parsedRoles)
                    {
                        claims.Add(new Claim(ClaimTypes.Role, parsedRole));
                    }
                }
                else
                {
                    claims.Add(new Claim(ClaimTypes.Role, roles.ToString()));
                }

                keyValuePairs.Remove(ClaimTypes.Role);
            }

            claims.AddRange(keyValuePairs.Select(kvp => new Claim(kvp.Key, kvp.Value.ToString())));
            return claims;
        }

        private byte[] ParsBase64WithoutPadding(string base64)
        {
            switch (base64.Length % 4)
            {
                case 2: base64 += "=="; break;
                case 3: base64 += "="; break;
            }

            return Convert.FromBase64String(base64);
        }

        public async Task Login(string token)
        {
            await js.SetInLocalStorage(TokenKey, token);
            var authState = BuildAuthenticationState(token);
            NotifyAuthenticationStateChanged(Task.FromResult(authState));
        }

        public async Task LogOut()
        {
            await js.RemoveItem(TokenKey);
            httpClient.DefaultRequestHeaders.Authorization = null;
            NotifyAuthenticationStateChanged(Task.FromResult(Anonymous));
        }
    }
}

在program.cs中:

    builder.Services.AddScoped<JWTAuthenticationStateProvider>();
    builder.Services.AddScoped<AuthenticationStateProvider, JWTAuthenticationStateProvider>
        (provider => provider.GetRequiredService<JWTAuthenticationStateProvider>());
    builder.Services.AddScoped<ILoginService, JWTAuthenticationStateProvider>
        (provider => provider.GetRequiredService<JWTAuthenticationStateProvider>());

【问题讨论】:

  • 本文档中提到的路径相关设置是什么:docs.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/…
  • 您好@Steve Greene 感谢您的回复。但我们的问题并没有解决。
  • 可能缺少 Microsoft.AspNetCore.Components.Authorization 的 DLL?可能值得检查此 dll 是否存在于已部署的版本中。
  • 感谢@Chris Campbell 我检查了 DLL 文件,它没有任何问题。我们在 Blazor 项目中使用 Dot Net 5 版本。

标签: blazor blazor-server-side


【解决方案1】:

只需将共享文件夹中脚本文件夹中的所有脚本复制到 wwwroot 文件夹中。 在 BLAZOR 中高于 5 的框架中运行网站时,必须复制上述文件夹中使用的所有脚本文件。因为IIS中默认定义的物理路径在共享层中没有直接访问这些文件夹的权限。 最好的问候。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多