I'm trying to implement .net core WebAPi + SignalR chatting server with vue.js client.
While I can find many references using SignalR and IdentityServer4, I found this useful library called dotnetify. The doetnetify author describes how to implement securepage using ASOS http://dotnetify.net/core/api/security. But I am stuck at validating withJwtsecurityTokenHandler.
I've tried replacing authentication server part which is implemented using ASOS with IdentityServer4 and copied all the custom implementation that author provided. But when Bearer token is passed to my chatting api, exception occurs on validating token with tokenValidationParameters that I manually changed.
My project setting is as below. IdentityServer4 with following apis and client configurations.
API configure:
return new List<ApiResource>
{
new ApiResource("api1", "API1" ),
new ApiResource("chatapi", "Chat API")
};
Client configure:
return new List<Client>
{
new Client
{
ClientId = "client",
ClientName = "JavaScript Client",
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
RequireConsent = false,
RedirectUris = { "http://localhost:8080/callback" },
PostLogoutRedirectUris = { "http://localhost:8080/login" },
AllowedCorsOrigins = { "http://localhost:8080" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
"api1",
"chatapi"
}
},
}
Sample implementation provided by dotnetify author: statup.cs https://github.com/dsuryd/dotNetify/blob/master/DevApp/server/Startup.cs AddAuthenticationServer.cs https://github.com/dsuryd/dotNetify/blob/master/DevApp/server/AuthServer.cs
I removed services.AddAuthenticationServer() and replaced with IdentityServer4's AddAuthentication("Bearer") as below.
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "https:/localhost:5000";
options.RequireHttpsMetadata = false;
options.ApiName = "chatapi";
});
services.AddCors(options =>
{
// this defines a CORS policy called "default"
options.AddPolicy("default", policy =>
{
policy.WithOrigins("http://localhost:8080",
Configuration["ClientAddress"])
.AllowAnyHeader()
.AllowAnyMethod();
});
});
and on Configure, I copied example and modified a tokenValidationParameters as below.
app.UseWebSockets();
app.UseSignalR(routes => routes.MapDotNetifyHub());
app.UseDotNetify(config =>
{
var tokenValidationParameters = new TokenValidationParameters {
ValidateIssuer = true,
ValidIssuer = "https://localhost:5000",
ValidAudience = "chatapi",
};
config.UseFilter<AuthorizeFilter>();
config.UseJwtBearerAuthentication(tokenValidationParameters);
config.UseMiddleware<ExtractAccessTokenMiddleware>(tokenValidationParameters);
// Demonstration filter that passes access token from the middleware to the ViewModels.SecurePageVM class instance.
config.UseFilter<SetAccessTokenFilter>();
});
The exception is as below.
Microsoft.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException: IDX10501: Signature validation failed. Unable to match keys:
kid: '[PII is hidden]',
token: '[PII is hidden]'.
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Foresting.Chat.ExamplePipelines.ExtractAccessTokenMiddleware.ValidateToken(HeaderData headers, SecurityToken& validatedToken) in C:\GitHub\ChatApi\ChatApi\ExamplePipelines\ExtractAccessTokenMiddleware.cs:line 46
at ChatApi.ExamplePipelines.ExtractAccessTokenMiddleware.Invoke(DotNetifyHubContext hubContext, NextDelegate next) in C:\GitHub\ChatApi\ChatApi\ExamplePipelines\ExtractAccessTokenMiddleware.cs:line 27
I suspect my tokenValidationParameter is not set right but no idea how to set it right and get it validated.
Tried to understand oid / oauth flow but it seems too complicated to understand and solve my problem in limited time.
Can anyone help me to where to look at to solve this kind of issue?
Thanks in advance.