在Asp.net SignalR与Angular通信添加身份认证(通过jwt)

这是一个复杂的东西,我查找了一些混乱的资料,最终在混乱的状态成功了,然后我尝试阅读代码,并删除了一些重复的东西,并以一种较为简洁的方式成功。

示例hubs端点

app.MapHub<MessageHub>("/hubs/message");

我假设你已经知道如何添加SignalR和通常的使用jwt的验证。

这包括

处理跨域, 添加身份,数据库,账户,驱动,身份验证。

在这种情况下,只需要额外添加

builder.Services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = jswSettings.Issuer,
            ValidAudience = jswSettings.Audience,
            IssuerSigningKey = new SymmetricSecurityKey(secretKey)
        };
        options.Events = new JwtBearerEvents();
    });
builder.Services.TryAddEnumerable(
    ServiceDescriptor.Singleton<IPostConfigureOptions<JwtBearerOptions>,
        ConfigureJwtBearerOptions>());

其中 

ConfigureJwtBearerOptions 是自定义的类,这个设计思路来自于微软的指南,是通过添加类似于中间件的形式实现。

如果不添加

options.Events = new JwtBearerEvents();

会在后面的(上面的)组件中提示空对象。

using Microsoft.IdentityModel.Tokens;

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Options;
public class ConfigureJwtBearerOptions : IPostConfigureOptions<JwtBearerOptions>
{
    public void PostConfigure(string? name, JwtBearerOptions options)
    {
        var originalOnMessageReceived = options.Events.OnMessageReceived;
        options.Events.OnMessageReceived = async context =>
        {
            await originalOnMessageReceived(context);

            if (string.IsNullOrEmpty(context.Token))
            {
                var accessToken = context.Request.Query["access_token"];
                var path = context.HttpContext.Request.Path;

                if (!string.IsNullOrEmpty(accessToken) &&
                    path.StartsWithSegments("/hubs/message"))
                {
                    context.Token = accessToken;
                }
            }
        };
        options.Events.OnAuthenticationFailed = context =>
        {
            if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
            {
                context.Response.Headers.Append("Token-Expired", "true");
            }
            else if (context.Exception.GetType() == typeof(SecurityTokenInvalidLifetimeException))
            {
                context.Response.Headers.Append("Token-Expired", "true");
            }

            return Task.CompletedTask;
        };
    }
}

 这个可以忽略

options.Events.OnAuthenticationFailed

主要的逻辑是 设置上下文的 token。

最后在中心上设置相应的要求

[Authorize(Policy = "user")]
public class MessageHub: Hub

这里使用的是之前配置的身份验证。

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("admin", policy => policy.RequireRole(["admin"]));
    options.AddPolicy("user", policy => policy.RequireRole(["user"]));
    options.AddPolicy("vip", policy => policy.RequireRole(["vip"]));
});

token中包含身份信息。在分发的token中包含。

private string GenerateToken(string username, int id)
    {
        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecretKey"]!));
        var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
        var roles = _context.AccountRoles!.Where(a => a.AccountId == id)
            .Include(r=>r.Role).ToList();
        var claims = new List<Claim> { new Claim(ClaimTypes.Name, username) };
        roles.ForEach(role =>
        {
            claims.Add(new Claim(ClaimTypes.Role,role.Role!.Name!));
        });
        var token = new JwtSecurityToken(
            issuer: _configuration["Jwt:Issuer"],
            audience: _configuration["Jwt:Audience"],
            claims: claims,
            expires: DateTime.Now.AddDays(3),
            signingCredentials: credentials);
        return new JwtSecurityTokenHandler().WriteToken(token);
    }

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要将ASP.NET Core Angular项目部署到IIS上,并且遇到"non-js module files deprecated"的问题。 首先,我们需要确保我们正在使用的是最新版本的ASP.NET Core和Angular。新版本通常会修复旧版中的已知问题。 然后,我们需要检查我们的Angular项目中是否有使用到非JS模块文件(non-js module files)。这些文件可能是早期版本中的遗留文件,因此被标记为过时(deprecated)。 要解决这个问题,我们可以按照以下步骤进行操作: 1. 检查Angular项目中的Angular.json配置文件。在该文件中,我们需要确保所有的非JS模块文件都被正确地排除在构建过程之外。这可以通过在 "build" 部分中的 "assets" 属性中排除这些文件来实现。 2. 确保我们使用的是正确的构建命令。在命令行或脚本中,我们应该使用 "ng build" 命令来构建我们的Angular项目,并确保在构建过程中自动排除非JS模块文件。例如,我们可以使用以下命令构建项目: ``` ng build --prod ``` 3. 删除任何已经存在的非JS模块文件,以避免将其错误地部署到服务器上。通常,这些文件可以在Angular项目的 "src" 目录中找到,并且可能以 ".css", ".html" 或 ".json" 结尾。 4. 部署我们的ASP.NET Core Angular项目到IIS。可以通过将项目文件复制到IIS网站目录中或使用自动化工具(例如Web Deploy)进行部署来实现。确保将ASP.NET Core应用程序部署为网站的子目录,以便正确配置IIS的应用程序池。 通过按照上述步骤进行操作,我们应该能够成功地将ASP.NET Core Angular项目部署到IIS上并解决"non-js module files deprecated"的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枫叶kx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值