前言

  SignalR Demo搭建起来之后,是没有相应的认证和授权功能的。于是乎,参考官方文档实现了相应的逻辑。

简单认证

  首先使用稍微简单的方式实现。添加如下代码:

 services.AddAuthentication(auth =>
{
auth.DefaultScheme = "User";
}).AddScheme<UserAuthenticationOptions, UserAuthenticationHandler>("User", o => { });

  

 public class UserAuthenticationOptions : AuthenticationSchemeOptions
{ }

  然后在新增Handler,重写 AuthenticationHandler 的HandleAuthenticateAsync 方法

  public class UserAuthenticationHandler : AuthenticationHandler<UserAuthenticationOptions>
{
private readonly ILayIMUserFactory userFactory; public UserAuthenticationHandler(IOptionsMonitor<UserAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IServiceProvider serviceProvider)
: base(options, logger, encoder, clock)
{
userFactory = serviceProvider.GetService<ILayIMUserFactory>();
}
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
var userId = userFactory.GetUserId(Request.HttpContext);
if (string.IsNullOrEmpty(userId))
{
return Task.FromResult(AuthenticateResult.Fail("no user"));
}
var claims = new[] { new Claim("user", userId) };
var identity = new ClaimsIdentity(claims, nameof(UserAuthenticationHandler));
var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), Scheme.Name);
return Task.FromResult(AuthenticateResult.Success(ticket));
}
}

  最后在Hub上增加AuthorizeAttribute即可

 [Authorize(AuthenticationSchemes = “User”)]
public class LayIMHub : Hub<ILayIMClient>{}

JWT Bearer认证

  首先安装 Microsoft.AspNetCore.Authentication.JwtBearer .

  然后在Startup中增加如下代码:(基本上就是官方教程中的)

 services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters =
new TokenValidationParameters
{
LifetimeValidator = (before, expires, token, param) =>
{
return expires > DateTime.UtcNow;
},
ValidateAudience = false,
ValidateIssuer = false,
ValidateActor = false,
ValidateLifetime = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(SignalRSecurityKey.TOKEN_KEY))
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"]; var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) &&
(path.StartsWithSegments("/layimHub")))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
});

  不过AuthorizeAttribute 的Scheme 要改成  JwtBearerDefaults.AuthenticationScheme. 运行一下程序,因为刚开始没有提供token,所以肯定是401的。

  

  对了,客户端连接的时候要加上accessTokenFactory:

        var options = {};
options.accessTokenFactory = () => token;
//options.skipNegotiation = true;
connection = new signalR.HubConnectionBuilder()
.configureLogging(signalR.LogLevel.Trace)
.withUrl(hubRoute, options)
.withHubProtocol(protocol)
.build();

  我们在实现一个获取Token的接口,在调用SignalR连接之前,先获取Token,然后把token带上即可。以下代码是生成Token的方法,Subject的内容可以随便定义

       var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(SignalRSecurityKey.TOKEN_KEY);
var authTime = DateTime.UtcNow;
var expiresAt = authTime.AddDays(7);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim("uid",userId)
}),
Expires = expiresAt,
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
return tokenString;

  下面在看演示:

  

  再次请求,已经带上了token头

  

  最后,在websocket握手阶段,也会将这个token传到后端。

 

  这样我们的程序就能正常运行了。

总结

  本文只是一篇简单的流水账记录。就酱吧

  代码地址:https://github.com/fanpan26/LayIM.AspNetCore/tree/master/src/LayIM.AspNetCore/LayIM.AspNetCore.IM.SignalR

使用Jwt为.Net Core SignalR保驾护航的更多相关文章

  1. .net core 3.0 Signalr - 05 使用jwt将用户跟signalr关联

    Signalr是以Group.Connect为核心来进行推送,比如,给某个组.某个连接来推送,但实际场景中,核心应该是某个组.某个人:然而一个人可以对应多个连接(浏览器多个tab页):本节就来介绍下自 ...

  2. Asp.Net Core SignalR 系列博客

    系列 SignalR+Vue SignalR+Vue 服务端向客户端发送信息 SignalR+Vue+Log4net 实时日志推送 待定...... 源码地址:https://github.com/Q ...

  3. ASP.NET Core SignalR中的流式传输

    什么是流式传输? 流式传输是这一种以稳定持续流的形式传输数据的技术. 流式传输的使用场景 有些场景中,服务器返回的数据量较大,等待时间较长,客户端不得不等待服务器返回所有数据后,再进行相应的操作.这时 ...

  4. Asp.Net Core SignalR 用泛型Hub优雅的调用前端方法及传参

    继续学习 最近一直在使用Asp.Net Core SignalR(下面成SignalR Core)为小程序提供websocket支持,前端时间也发了一个学习笔记,在使用过程中稍微看了下它的源码,不得不 ...

  5. Asp.Net Core SignalR 与微信小程序交互笔记

    什么是Asp.Net Core SignalR Asp.Net Core SignalR 是微软开发的一套基于Asp.Net Core的与Web进行实时交互的类库,它使我们的应用能够实时的把数据推送给 ...

  6. [asp.net core]SignalR一个例子

    摘要 在一个后台管理的页面想实时监控一些操作的数据,想到用signalR. 一个例子 asp.net core+signalR 使用Nuget安装包:Microsoft.AspNetCore.Sign ...

  7. ASP.NET Core SignalR

    ASP.NET Core SignalR 是微软开发的一套基于ASP.NET Core的与Web进行实时交互的类库,它使我们的应用能够实时的把数据推送给Web客户端. 功能 自动管理连接 允许同时广播 ...

  8. Net Core SignalR 测试,可以用于unity、Layair、白鹭引擎、大数据分析平台等高可用消息实时通信器。

    SignalR介绍 SignalR介绍来源于微软文档,不过多解释.https://docs.microsoft.com/zh-cn/aspnet/core/signalr/introduction?v ...

  9. LayIM.AspNetCore Middleware 开发日记(七)Asp.Net.Core.SignalR闪亮登场

    前言   前几篇介绍了整个中间件的构成,路由,基本配置等等.基本上没有涉及到通讯部分.不过已经实现了融云的通讯功能,由于是第三方的就不在单独去写.正好.NET Core SignalR已经出来好久了, ...

随机推荐

  1. Cheatsheet: 2018 11.01 ~ 2019 02.28

    Golang FromXToGo micro - A microservice toolkit Other Easy parsing of Excel spreadsheet format with ...

  2. [PHP] 通用网关接口CGI 的运行原理

    CGI 的运行原理:1.客户端访问某个 URL 地址之后,通过 GET/POST/PUT 等方式提交数据,并通过 HTTP 协议向 Web 服务器发出请求.2.服务器端的 HTTP Daemon(守护 ...

  3. windbg .net 程序的死锁检测 常用方法(个人备份笔记)

    //死锁检测 .load sosex.dll :> !dlk :> !mk -a The mk command displays a call stack of the currently ...

  4. 《JavaWeb从入门到改行》关于BaseServlet那些事

    @为什么需要BaseServlet?  我们知道一个POST或者GET提交对应着一个Servlet, 无数的提交会让Servlet页面增加,我们希望一个Servlet就能处理很多提交的请求. @Bas ...

  5. 【VS2012】F5不能自动编译新修改

    VS2012正常使用时,如果文件有修改,按F5运行时,会自动对修改的文件进行重新编译.今天遇到的情况却并没有.度娘了下,网上有相同的问题,解决办法是“工具->选项->项目和解决方案-> ...

  6. webstorm 打开后 一直停留在scanning files to index....,或跳出内存不够的提示框

    用着有时会这样,超级卡, 网上搜了下,原来如此,记录下,免得忘了. ------------------------- 说明: 在npm install 后,会出现Scanning files to ...

  7. 剑指Offer-编程详解-二维数组中的查找

    题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ...

  8. Java 之集合框架 上(9)

    Java 中的集合框架 如果一个类中存在很多相同类型的属性. 例如:学生类 学生可以选课,因此存在很多课程类型的属性.但是每个学生选择的课程的种类和数量是不一样的. 如果将每一个课程类型的属性都列到课 ...

  9. activiti查询

    一  1.根据当前任务id获得当前任务对象  Task task = processEngine.getTaskService().createTaskQuery().taskId(taskId).s ...

  10. [翻译] ZLSwipeableView

    ZLSwipeableView A simple view for building card like interface like Tinder and Potluck. ZLSwipeableV ...