JWT C# Sample
This commit is contained in:
parent
a4dd0cd9d7
commit
4394b57143
|
|
@ -91,6 +91,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Signal
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JwtSample", "samples\JwtSample\JwtSample.csproj", "{6A7491D3-3C97-49BD-A71C-433AED657F30}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JwtSample", "samples\JwtSample\JwtSample.csproj", "{6A7491D3-3C97-49BD-A71C-433AED657F30}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JwtClientSample", "samples\JwtClientSample\JwtClientSample.csproj", "{1A953296-E869-4DE2-A693-FD5FCDE27057}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|
@ -201,6 +203,10 @@ Global
|
||||||
{6A7491D3-3C97-49BD-A71C-433AED657F30}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{6A7491D3-3C97-49BD-A71C-433AED657F30}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{6A7491D3-3C97-49BD-A71C-433AED657F30}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{6A7491D3-3C97-49BD-A71C-433AED657F30}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{6A7491D3-3C97-49BD-A71C-433AED657F30}.Release|Any CPU.Build.0 = Release|Any CPU
|
{6A7491D3-3C97-49BD-A71C-433AED657F30}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{1A953296-E869-4DE2-A693-FD5FCDE27057}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{1A953296-E869-4DE2-A693-FD5FCDE27057}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{1A953296-E869-4DE2-A693-FD5FCDE27057}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{1A953296-E869-4DE2-A693-FD5FCDE27057}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
@ -233,6 +239,7 @@ Global
|
||||||
{BE982591-F4BB-42D9-ABD4-A5D44C65971E} = {DA69F624-5398-4884-87E4-B816698CDE65}
|
{BE982591-F4BB-42D9-ABD4-A5D44C65971E} = {DA69F624-5398-4884-87E4-B816698CDE65}
|
||||||
{0B083AE6-86CA-4E0B-AE02-59154D1FD005} = {6A35B453-52EC-48AF-89CA-D4A69800F131}
|
{0B083AE6-86CA-4E0B-AE02-59154D1FD005} = {6A35B453-52EC-48AF-89CA-D4A69800F131}
|
||||||
{6A7491D3-3C97-49BD-A71C-433AED657F30} = {C4BC9889-B49F-41B6-806B-F84941B2549B}
|
{6A7491D3-3C97-49BD-A71C-433AED657F30} = {C4BC9889-B49F-41B6-806B-F84941B2549B}
|
||||||
|
{1A953296-E869-4DE2-A693-FD5FCDE27057} = {C4BC9889-B49F-41B6-806B-F84941B2549B}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {7945A4E4-ACDB-4F6E-95CA-6AC6E7C2CD59}
|
SolutionGuid = {7945A4E4-ACDB-4F6E-95CA-6AC6E7C2CD59}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFrameworks>netcoreapp2.0</TargetFrameworks>
|
||||||
|
<!-- Don't create a NuGet package -->
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.SignalR.Client\Microsoft.AspNetCore.SignalR.Client.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
|
using Microsoft.AspNetCore.Sockets;
|
||||||
|
|
||||||
|
namespace JwtClientSample
|
||||||
|
{
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static async Task Main(string[] args)
|
||||||
|
{
|
||||||
|
var app = new Program();
|
||||||
|
await Task.WhenAll(
|
||||||
|
app.RunConnection(TransportType.WebSockets),
|
||||||
|
app.RunConnection(TransportType.ServerSentEvents),
|
||||||
|
app.RunConnection(TransportType.LongPolling));
|
||||||
|
}
|
||||||
|
|
||||||
|
private const string ServerUrl = "http://localhost:54543";
|
||||||
|
|
||||||
|
private readonly ConcurrentDictionary<string, string> _tokens = new ConcurrentDictionary<string, string>();
|
||||||
|
private readonly Random _random = new Random();
|
||||||
|
|
||||||
|
private async Task RunConnection(TransportType transportType)
|
||||||
|
{
|
||||||
|
var userId = "C#" + transportType.ToString();
|
||||||
|
_tokens[userId] = await GetJwtToken(userId);
|
||||||
|
|
||||||
|
var hubConnection = new HubConnectionBuilder()
|
||||||
|
.WithUrl(ServerUrl + "/broadcast")
|
||||||
|
.WithTransport(transportType)
|
||||||
|
.WithJwtBearer(() => _tokens[userId])
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
hubConnection.On<string, string>("Message", (sender, message) => Console.WriteLine($"[{userId}] {sender}: {message}"));
|
||||||
|
await hubConnection.StartAsync();
|
||||||
|
Console.WriteLine($"[{userId}] Connection Started");
|
||||||
|
|
||||||
|
var ticks = 0;
|
||||||
|
var nextMsgAt = 3;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (!hubConnection.Closed.IsCompleted)
|
||||||
|
{
|
||||||
|
await Task.Delay(1000);
|
||||||
|
ticks++;
|
||||||
|
if (ticks % 15 == 0)
|
||||||
|
{
|
||||||
|
// no need to refresh the token for websockets
|
||||||
|
if (transportType != TransportType.WebSockets)
|
||||||
|
{
|
||||||
|
_tokens[userId] = await GetJwtToken(userId);
|
||||||
|
Console.WriteLine($"[{userId}] Token refreshed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ticks % nextMsgAt == 0)
|
||||||
|
{
|
||||||
|
await hubConnection.SendAsync("Broadcast", userId, $"Hello at {DateTime.Now.ToString()}");
|
||||||
|
nextMsgAt = _random.Next(2, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[{userId}] Connection terminated with error: {ex}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<string> GetJwtToken(string userId)
|
||||||
|
{
|
||||||
|
var httpResponse = await new HttpClient().GetAsync(ServerUrl + $"/generatetoken?user={userId}");
|
||||||
|
httpResponse.EnsureSuccessStatusCode();
|
||||||
|
return await httpResponse.Content.ReadAsStringAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -38,6 +38,7 @@ namespace JwtSample
|
||||||
options.TokenValidationParameters =
|
options.TokenValidationParameters =
|
||||||
new TokenValidationParameters
|
new TokenValidationParameters
|
||||||
{
|
{
|
||||||
|
LifetimeValidator = (before, expires, token, parameters) => expires > DateTime.UtcNow,
|
||||||
ValidateAudience = false,
|
ValidateAudience = false,
|
||||||
ValidateIssuer = false,
|
ValidateIssuer = false,
|
||||||
ValidateActor = false,
|
ValidateActor = false,
|
||||||
|
|
@ -76,7 +77,7 @@ namespace JwtSample
|
||||||
{
|
{
|
||||||
var claims = new[] { new Claim(ClaimTypes.NameIdentifier, httpContext.Request.Query["user"]) };
|
var claims = new[] { new Claim(ClaimTypes.NameIdentifier, httpContext.Request.Query["user"]) };
|
||||||
var credentials = new SigningCredentials(SecurityKey, SecurityAlgorithms.HmacSha256);
|
var credentials = new SigningCredentials(SecurityKey, SecurityAlgorithms.HmacSha256);
|
||||||
var token = new JwtSecurityToken("SignalRTestServer", "SignalRTests", claims, expires: DateTime.Now.AddSeconds(30), signingCredentials: credentials);
|
var token = new JwtSecurityToken("SignalRTestServer", "SignalRTests", claims, expires: DateTime.UtcNow.AddSeconds(30), signingCredentials: credentials);
|
||||||
return JwtTokenHandler.WriteToken(token);
|
return JwtTokenHandler.WriteToken(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,6 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GenerateJwtToken()
|
private string GenerateJwtToken()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue