Reputation: 303
I’m trying to convert this method into F#
private static bool VerifySignedJwt(ECDsa eCDsa, string token) {
var tokenHandler = new JwtSecurityTokenHandler();
var claimsPrincipal = tokenHandler.ValidateToken(token, new TokenValidationParameters {
ValidIssuer = "me",
ValidAudience = "you",
IssuerSigningKey = new ECDsaSecurityKey(eCDsa)
}, out var parsedToken);
return claimsPrincipal.Identity.IsAuthenticated;
}
I’m translating this great piece of work by Scott Brady in order to create and validate JWT tokens for a web app, the creation part went without a hitch. On with the Validation part and the reference to a byref required in the JwtSecurityTokenHandler.ValidateToken method has stumped me. https://www.scottbrady91.com/C-Sharp/JWT-Signing-using-ECDSA-in-dotnet-Core
If I follow the Microsoft docs below; I get an error saying a “type instantiation involves a byref type. This is not permitted by the rules of Common IL.” When trying to declare a byref as:
let _h (x: byref<'T>) = ()
https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/byrefs I have read the Microsoft docs on byrefs but am left wondering if this relates to .Net core or F#4.5 or does dotnet core supersede all features including byrefs in F#4.5? Either way I can’t seem to instantiate a SecurityToken at all, the "out var parsedToken" is a SecurityToken type, let alone a byref one to use as an output to this 3rd party library, or I can’t seem to declare a byref SecurityToken directly in the call to JwtSecurityTokenHandler.ValidateToken.
If I use the advice posted in this SO post Using c# delegates with f# functions
let function_1 (x:double) (y:double byref) =
y <- 6.0
I get the same error “type instantiation involves a byref type. This is not permitted by the rules of Common IL.”
I have used Byrefs before in F# but these were simple integer types and worked without issue. My project is .Net core 2.1
Any help appreciated.
Upvotes: 2
Views: 233
Reputation: 1991
Since the out
parameter in the ValidateToken()
call is the last one, you can simply omit it, and treat it as a second return value:
let claimsPrincipal, parsedToken = tokenHandler.ValidateToken (token, tvp)
(Here tvp
would be your TokenValidationParameters
instance.)
See also https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/parameters-and-arguments#passing-by-reference for more information.
EDIT: Since you don't seem to be using the second return value, I figure your function could look as follows:
let verifySignedJwt ecdsa token =
let tokenHandler = JwtSecurityTokenHandler ()
let tvp = TokenValidationParameters (ValidIssuer = "me",
ValidAudience = "you",
IssuerSigningKey = ECDsaSecurityKey ecdsa)
let claimsPrincipal, _ = tokenHandler.ValidateToken (token, tvp)
claimsPrincipal.Identity.IsAuthenticated
Upvotes: 3
Reputation: 5005
An alternative (not necessarily better) would be this:
let mutable parsedToken = initialValue
let claimsPrinciple = tokenHandler.ValidateToken(token, tvp, &parsedToken)
// something with both
The above is useful if you have multiple byref
parameters, or you don't have the pattern of a single byref
parameter at the very end.
Upvotes: 1