user1796185
user1796185

Reputation: 303

c# to f# when 3rd party lib wants a byref as an out parameter

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

Answers (2)

dumetrulo
dumetrulo

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

Phillip Carter
Phillip Carter

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

Related Questions