transferir la implementación de autenticación JWT de .net core 2 a asp.net web api 2
tengo implementación deAutenticación JWT enaplicación .net core 2Funciona bien.
Quiero usar esta implementación y estructura enasp.net web api 2 aplicación pero recibo un error
mi estructura:
Clase JwtTokenBuilder:
using System;
using System.Collections.Generic;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Linq;
namespace solution.Authentication
{
public sealed class JwtTokenBuilder
{
private SecurityKey securityKey = null;
private string subject = "";
private string issuer = "";
private string audience = "";
private Dictionary<string, string> claims = new Dictionary<string, string>();
private DateTime expireTime = DateTime.UtcNow.AddMinutes(30);
public JwtTokenBuilder AddSecurityKey(SecurityKey securityKey)
{
this.securityKey = securityKey;
return this;
}
public JwtTokenBuilder AddSubject(string subject)
{
this.subject = subject;
return this;
}
public JwtTokenBuilder AddIssuer(string issuer)
{
this.issuer = issuer;
return this;
}
public JwtTokenBuilder AddAudience(string audience)
{
this.audience = audience;
return this;
}
public JwtTokenBuilder AddClaim(string type, string value)
{
this.claims.Add(type, value);
return this;
}
public JwtTokenBuilder AddClaims(Dictionary<string, string> claims)
{
this.claims.Union(claims);
return this;
}
public JwtTokenBuilder AddExpiry(DateTime expireTime)
{
this.expireTime = expireTime;
return this;
}
public JwtToken Build()
{
EnsureArguments();
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, this.subject),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
}
.Union(this.claims.Select(item => new Claim(item.Key, item.Value)));
var token = new JwtSecurityToken(
issuer: this.issuer,
audience: this.audience,
claims: claims,
expires: this.expireTime,
signingCredentials: new SigningCredentials(
this.securityKey,
SecurityAlgorithms.HmacSha256));
return new JwtToken(token);
}
#region " private "
private void EnsureArguments()
{
if (this.securityKey == null)
throw new ArgumentNullException("Security Key");
if (string.IsNullOrEmpty(this.subject))
throw new ArgumentNullException("Subject");
if (string.IsNullOrEmpty(this.issuer))
throw new ArgumentNullException("Issuer");
if (string.IsNullOrEmpty(this.audience))
throw new ArgumentNullException("Audience");
}
#endregion
}
}
Objeto token:
using System;
using System.IdentityModel.Tokens.Jwt;
namespace solution.Authentication
{
public sealed class JwtToken
{
private JwtSecurityToken token;
internal JwtToken(JwtSecurityToken token)
{
this.token = token;
}
public DateTime ValidTo => token.ValidTo;
public string access_token => new JwtSecurityTokenHandler().WriteToken(this.token);
}
}
clase de clave de seguridad:
using Microsoft.IdentityModel.Tokens;
using System.Text;
namespace solution.Authentication
{
public static class JwtSecurityKey
{
public static SymmetricSecurityKey Create(string secret)
{
return new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret));
}
}
}
mi método de controlador de token paragenerar y volversimbólico :
private JwtToken getToken(User user)
{
DateTime startTime = DateTime.Now;
DateTime expireTime = DateTime.Now.AddMinutes(60);
var token = new JwtTokenBuilder()
.AddSecurityKey(JwtSecurityKey.Create("SecurityKey"))
.AddSubject("Subject")
.AddIssuer("Issuer")
.AddAudience("Audience")
.AddClaim("Username", user.UserName)
.AddExpiry(expireTime)
.Build();
return token;
}
en la aplicación .net core 2 que usoOWIN Clase de inicio paravalidar misimbólico para todos los controladores que tienenAutorizar atributo.
ejemplo de controlador:
namespace solution.Controllers
{
public class ExampleController : ApiController
{
[HttpPost]
[Route("api/Example")]
[Authorize(Policy = "Session")]
public void Run()
{
// do something;
}
}
}
mi clase de inicio owin para validar el token JWT:
,using System;
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Threading.Tasks;
namespace solution
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "Issuer",
ValidAudience = "Audience",
IssuerSigningKey = JwtSecurityKey.Create("SecurityKey")
};
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
return Task.CompletedTask;
},
OnTokenValidated = context =>
{
return Task.CompletedTask;
}
};
});
services.AddAuthorization(options =>
{
options.AddPolicy("Session", policy => policy.RequireClaim("SessionId"));
});
services.AddSignalR();
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.Use(async (context, next) =>
{
await next();
if (context.Response.StatusCode == 404 &&
!Path.HasExtension(context.Request.Path.Value) &&
!context.Request.Path.Value.StartsWith("/api/", StringComparison.OrdinalIgnoreCase))
{
context.Request.Path = "/index.html";
await next();
}
});
app.UseDeveloperExceptionPage();
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseCors(policyName: "CorsPolicy");
app.UseSignalR(routes =>
{
});
}
}
}
quiero usar esta estructura enasp.net web api solo cambioOwin clase, es posible? por favor ayudame para cualquier cambio