美文网首页.NET
.NET CORE SignalR JWT授权认证

.NET CORE SignalR JWT授权认证

作者: 老中医167788 | 来源:发表于2020-03-30 16:10 被阅读0次

    服务端

    安装依赖

    • Microsoft.AspNetCore.Authentication.JwtBearer

    Broadcaster.cs:

    // Copyright (c) .NET Foundation. All rights reserved.
    // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
    
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Authentication.JwtBearer;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.SignalR;
    
    namespace JwtSample
    {
        [Authorize(JwtBearerDefaults.AuthenticationScheme)]
        public class Broadcaster : Hub
        {
            public Task Broadcast(string sender, string message) =>
                Clients.All.SendAsync("Message", sender, message);
        }
    }
    

    Program.cs:

    // Copyright (c) .NET Foundation. All rights reserved.
    // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
    
    using System.IO;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Logging;
    
    namespace JwtSample
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                new WebHostBuilder()
                    .ConfigureLogging(factory =>
                    {
                        factory.AddConsole();
                        factory.AddFilter("Console", level => level >= LogLevel.Information);
                        factory.AddDebug();
                    })
                    .UseKestrel()
                    .UseContentRoot(Directory.GetCurrentDirectory())
                    .UseIISIntegration()
                    .UseStartup<Startup>()
                    .Build()
                    .Run();
            }
        }
    }
    

    Startup.cs:

    // Copyright (c) .NET Foundation. All rights reserved.
    // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
    
    using System;
    using System.IdentityModel.Tokens.Jwt;
    using System.Security.Claims;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Authentication.JwtBearer;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Routing;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.IdentityModel.Tokens;
    
    namespace JwtSample
    {
        public class Startup
        {
            private readonly SymmetricSecurityKey SecurityKey = new SymmetricSecurityKey(Guid.NewGuid().ToByteArray());
            private readonly JwtSecurityTokenHandler JwtTokenHandler = new JwtSecurityTokenHandler();
    
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddSignalR();
                services.AddAuthorization(options =>
                {
                    options.AddPolicy(JwtBearerDefaults.AuthenticationScheme, policy =>
                    {
                        policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
                        policy.RequireClaim(ClaimTypes.NameIdentifier);
                    });
                });
    
                services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                    .AddJwtBearer(options =>
                    {
                        options.TokenValidationParameters =
                        new TokenValidationParameters
                        {
                            LifetimeValidator = (before, expires, token, parameters) => expires > DateTime.UtcNow,
                            ValidateAudience = false,
                            ValidateIssuer = false,
                            ValidateActor = false,
                            ValidateLifetime = true,
                            IssuerSigningKey = SecurityKey
                        };
    
                        options.Events = new JwtBearerEvents
                        {
                            OnMessageReceived = context =>
                            {
                                var accessToken = context.Request.Query["access_token"];
    
                                if (!string.IsNullOrEmpty(accessToken) &&
                                    (context.HttpContext.WebSockets.IsWebSocketRequest || context.Request.Headers["Accept"] == "text/event-stream"))
                                {
                                    context.Token = context.Request.Query["access_token"];
                                }
                                return Task.CompletedTask;
                            }
                        };
                    });
            }
    
            public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                app.UseFileServer();
                app.UseSignalR(options => options.MapHub<Broadcaster>("/broadcast"));
    
                var routeBuilder = new RouteBuilder(app);
                routeBuilder.MapGet("generatetoken", c => c.Response.WriteAsync(GenerateToken(c)));
                app.UseRouter(routeBuilder.Build());
            }
    
            private string GenerateToken(HttpContext httpContext)
            {
                var claims = new[] { new Claim(ClaimTypes.NameIdentifier, httpContext.Request.Query["user"]) };
                var credentials = new SigningCredentials(SecurityKey, SecurityAlgorithms.HmacSha256);
                var token = new JwtSecurityToken("SignalRTestServer", "SignalRTests", claims, expires: DateTime.UtcNow.AddSeconds(30), signingCredentials: credentials);
                return JwtTokenHandler.WriteToken(token);
            }
        }
    }
    

    客户端

    安装依赖

    • Microsoft.AspNetCore.SignalR.Client
    using Microsoft.AspNetCore.Http.Connections;
    using Microsoft.AspNetCore.SignalR.Client;
    using System;
    using System.Collections.Concurrent;
    using System.Net.Http;
    using System.Threading.Tasks;
    
    namespace ConsoleClient
    {
        class Program
        {
            const string ServerUrl = "http://localhost:5000";
            static async Task Main(string[] args)
            {
                await Task.Run(() => new Program().RunConnection(HttpTransportType.WebSockets));
            }
    
            async Task RunConnection(HttpTransportType transportType)
            {
                var userId = new Random().Next(2, 19).ToString();
                // 参数
                var hubConnection = new HubConnectionBuilder()
                    .WithUrl($"{ServerUrl}/broadcast", options =>
                    {
                        options.Transports = transportType;
                        options.AccessTokenProvider = () => GetJwtToken(userId);
                    }).Build();
    
                // 消息接收
                hubConnection.On<string, string>("Message", (sender, message) => {
                    Console.WriteLine($"[{userId}]\n{sender}:{message}");
                });
                
                // 建立连接
                await hubConnection.StartAsync();
                Console.WriteLine($"[{userId}] Connection Started...");
    
                // 向服务端发送一条消息
                await hubConnection.SendAsync("Broadcast", userId, $"Hello at {DateTime.Now.ToString()}");
    
                Console.ReadKey(true);
            }
            
            // 取Token
            async Task<string> GetJwtToken(string userId)
            {
                var httpResponse = await new HttpClient().GetAsync($"{ServerUrl}/generatetoken?user={userId}");
                httpResponse.EnsureSuccessStatusCode();
                return await httpResponse.Content.ReadAsStringAsync();
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:.NET CORE SignalR JWT授权认证

        本文链接:https://www.haomeiwen.com/subject/dlpvuhtx.html