JWT C# Sample

This commit is contained in:
Pawel Kadluczka 2017-11-16 17:05:55 -08:00 committed by Pawel Kadluczka
parent a4dd0cd9d7
commit 4394b57143
5 changed files with 103 additions and 2 deletions

View File

@ -91,6 +91,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Signal
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JwtSample", "samples\JwtSample\JwtSample.csproj", "{6A7491D3-3C97-49BD-A71C-433AED657F30}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JwtClientSample", "samples\JwtClientSample\JwtClientSample.csproj", "{1A953296-E869-4DE2-A693-FD5FCDE27057}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
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}.Release|Any CPU.ActiveCfg = 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
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -233,6 +239,7 @@ Global
{BE982591-F4BB-42D9-ABD4-A5D44C65971E} = {DA69F624-5398-4884-87E4-B816698CDE65}
{0B083AE6-86CA-4E0B-AE02-59154D1FD005} = {6A35B453-52EC-48AF-89CA-D4A69800F131}
{6A7491D3-3C97-49BD-A71C-433AED657F30} = {C4BC9889-B49F-41B6-806B-F84941B2549B}
{1A953296-E869-4DE2-A693-FD5FCDE27057} = {C4BC9889-B49F-41B6-806B-F84941B2549B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7945A4E4-ACDB-4F6E-95CA-6AC6E7C2CD59}

View File

@ -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>

View File

@ -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();
}
}
}

View File

@ -38,6 +38,7 @@ namespace JwtSample
options.TokenValidationParameters =
new TokenValidationParameters
{
LifetimeValidator = (before, expires, token, parameters) => expires > DateTime.UtcNow,
ValidateAudience = false,
ValidateIssuer = false,
ValidateActor = false,
@ -76,7 +77,7 @@ namespace JwtSample
{
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.Now.AddSeconds(30), signingCredentials: credentials);
var token = new JwtSecurityToken("SignalRTestServer", "SignalRTests", claims, expires: DateTime.UtcNow.AddSeconds(30), signingCredentials: credentials);
return JwtTokenHandler.WriteToken(token);
}
}

View File

@ -63,7 +63,6 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests
return;
}
});
}
private string GenerateJwtToken()