sso*_*orl 6 f# jwt asp.net-core
我一直在使用F#制作Web api,主要是按照本指南进行操作:https : //www.blinkingcaret.com/2017/09/06/secure-web-api-in-asp-net-core/。但是,每当我尝试在aspnet webapi中命中经过身份验证的终结点时,都会出现此错误:
Failed to validate the token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiciIsImV4cCI6IjE1MjI2MzUwNDMiLCJuYmYiOiIxNTIyNTQ4NjQzIn0.VofLygSMitkmEsTBFNG-7-3jMAZYkyvfwc2UIs7AIyw.
Microsoft.IdentityModel.Tokens.SecurityTokenInvalidSignatureException: IDX10500: Signature validation failed. No security keys were provided to validate the signature.
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 Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.<HandleAuthenticateAsync>d__6.MoveNext()
Run Code Online (Sandbox Code Playgroud)
我在这里发现了类似的问题,但没有一个解决方案对我有帮助。我的Startup.fs样子是:
type Startup private () =
new (configuration: IConfiguration) as this =
Startup() then
this.Configuration <- configuration
// This method gets called by the runtime. Use this method to add services to the container.
member this.ConfigureServices(services: IServiceCollection) =
// Add framework services
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(fun options ->
options.TokenValidationParameters = TokenValidationParameters (
ValidateAudience = false,
ValidateIssuer = false,
ValidateIssuerSigningKey = true,
IssuerSigningKey = SymmetricSecurityKey(Encoding.UTF8.GetBytes("the secret that needs to be at least 16 characeters long for HmacSha256")),
ValidateLifetime = false, //validate the expiration and not before values in the token
ClockSkew = TimeSpan.FromMinutes(5.0) //5 minute tolerance for the expiration date
) |> ignore
) |> ignore
services.AddMvc() |> ignore
services.AddSwaggerGen (fun c -> c.SwaggerDoc("v1", Swagger.Info())) |> ignore
services.AddCors() |> ignore
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
member this.Configure(app: IApplicationBuilder, env: IHostingEnvironment) =
app.UseExceptionHandler(
fun options ->
options.Run(
fun context ->
let ex = context.Features.Get<IExceptionHandlerFeature>()
match ex.Error with
| HttpCodedException (code, message) ->
printfn "code: %i, msg: %s" (int code) message
context.Response.StatusCode <- int code
context.Response.WriteAsync(message)
| exn -> raise (exn)
)
) |> ignore
// let cors = Action<CorsPolicyBuilder> (fun builder -> builder.WithOrigins("http://localhost:3000").AllowAnyHeader().AllowAnyMethod() |> ignore)
app.UseCors(fun policy ->
policy.AllowAnyHeader()
.AllowAnyOrigin()
.AllowCredentials()
.AllowAnyMethod()
.Build() |> ignore
) |> ignore
app.UseAuthentication() |> ignore
app.UseMvc() |> ignore
member val Configuration : IConfiguration = null with get, set
Run Code Online (Sandbox Code Playgroud)
我已经尝试关闭所有验证,所以我很困惑为什么仍然失败。如果有帮助,我生成令牌的地方如下所示:
let GenerateToken (username) =
let claims = [|
Claim (ClaimTypes.Name, username)
Claim (JwtRegisteredClaimNames.Exp, DateTimeOffset(DateTime.Now.AddDays(1.0)).ToUnixTimeSeconds().ToString())
Claim (JwtRegisteredClaimNames.Nbf, DateTimeOffset(DateTime.Now).ToUnixTimeSeconds().ToString())
|]
let cred =
new SigningCredentials(
SymmetricSecurityKey(Encoding.UTF8.GetBytes("the secret that needs to be at least 16 characeters long for HmacSha256")),
SecurityAlgorithms.HmacSha256
)
let token = JwtSecurityToken(JwtHeader(cred), JwtPayload(claims))
JwtSecurityTokenHandler().WriteToken(token)
Run Code Online (Sandbox Code Playgroud)
希望有人可以看到我在做什么错。
终于明白了这一点。F# 不用于=赋值,它使用<-. 因此需要将我的服务 AddAuthenticaton 调用更改为:
services.AddAuthentication(fun options ->
options.DefaultScheme <- JwtBearerDefaults.AuthenticationScheme
options.DefaultAuthenticateScheme <- JwtBearerDefaults.AuthenticationScheme
options.DefaultChallengeScheme <- JwtBearerDefaults.AuthenticationScheme
).AddJwtBearer(fun options ->
options.TokenValidationParameters <- TokenValidationParameters (
ValidateAudience = false,
ValidateIssuer = false,
ValidateIssuerSigningKey = false,
IssuerSigningKey = SymmetricSecurityKey(Encoding.UTF8.GetBytes("the secret that needs to be at least 16 characeters long for HmacSha256")),
ValidateLifetime = false, //validate the expiration and not before values in the token
ClockSkew = TimeSpan.FromMinutes(5.0), //5 minute tolerance for the expiration date
ValidateActor = false,
ValidateTokenReplay = false
)
) |> ignore
Run Code Online (Sandbox Code Playgroud)
现在一切正常。
| 归档时间: |
|
| 查看次数: |
2584 次 |
| 最近记录: |