具有自定义身份验证类型的ASP.NET Core JWT

时间:2020-07-14 18:36:13

标签: asp.net-core authentication f# jwt bearer-token

是否可以为HTTP授权标头配置身份验证类型?例如:“令牌”而不是“承载者”?

请考虑以下扩展方法,该方法可激活身份验证并使用名为“令牌”的自定义方案配置JWT:

let jwtScheme = "Token" 

type IServiceCollection with
    member this.AddJwtAuthentication (JwtSecret jwtSecret : JwtSecret) =                 
        this.AddAuthentication(jwtScheme)            
            .AddJwtBearer(jwtScheme, jwtScheme, fun jwt ->                  
                jwt.RequireHttpsMetadata <- false
                jwt.SaveToken <- true 
                                    
                let key = Encoding.ASCII.GetBytes jwtSecret
                let validationParams = TokenValidationParameters()             
                    
                validationParams.IssuerSigningKey <- SymmetricSecurityKey(key)
                validationParams.ValidateIssuerSigningKey <- true
                validationParams.ValidateIssuer <- false
                validationParams.ValidateAudience <- false
                    
                jwt.TokenValidationParameters <- validationParams)                
            |> ignore
        this

此请求(具有Bearer身份验证类型)已成功处理

GET /user HTTP/1.1
Host: https://localhost:5001/api
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9zaWQiOiIxIiwibmFtZWlkIjoicGltIiwibmJmIjoxNTk0NzUxMTA1LCJleHAiOjE1OTUzNTU5MDUsImlhdCI6MTU5NDc1MTEwNX0.G3P7JR97rKG9ckX9UD0kHtZ8sNWOKYsJDrFY5bz3RqE

未成功处理此请求(具有Token身份验证类型的请求):

GET /user HTTP/1.1
Host: https://localhost:5001/api
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9zaWQiOiIxIiwibmFtZWlkIjoicGltIiwibmJmIjoxNTk0NzUxMTA1LCJleHAiOjE1OTUzNTU5MDUsImlhdCI6MTU5NDc1MTEwNX0.G3P7JR97rKG9ckX9UD0kHtZ8sNWOKYsJDrFY5bz3RqE

1 个答案:

答案 0 :(得分:1)

解决方案是插入JwtBearerEvents并删除Token 前缀(如果存在的话):

this.AddAuthentication(jwtScheme)               
    .AddJwtBearer(jwtScheme, fun jwt ->                                  
        let events = JwtBearerEvents()
        
        events.OnMessageReceived <- (fun ctx ->
            let authHeader = ctx.HttpContext.Request.Headers.["Authorization"].ToArray()
            match Array.tryHead authHeader with
            | None   -> ()
            | Some header -> 
                match header.StartsWith("Token ", StringComparison.OrdinalIgnoreCase) with
                | false -> ()
                | true  ->
                    ctx.Token <- header.Substring("Token ".Length).Trim()

            Task.CompletedTask)

        jwt.Events <- events

        // Rest of options ...)                
    |> ignore