Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go Language and Verify JWT

Tags:

I have been searching for an example I can understand of how to validate the signature of a JWT with the GO Language.

This might be especially tricky since I am using Okta, and it uses JWKs, so it is not especially straight forward.

When I receive a JWT, I can decode it no problem, just get stuck on how to verify the signature.

Below I have included a JWT, and the JWK details. If anyone is comfortable with this, and can complete signature validation with an Example, that would be amazing.:)

You can get to all of this information here: https://oktaproxy.com/oidcgenerator.php, this site will generate a JWT from Okta, and the keys can be obtained here: https://companyx.okta.com/oauth2/v1/keys.

Here is the JWT:

eyJhbGciOiJSUzI1NiIsImtpZCI6Ind5TXdLNEE2Q0w5UXcxMXVvZlZleVExMTlYeVgteHlreW1ra1h5Z1o1T00ifQ.eyJzdWIiOiIwMHUxOGVlaHUzNDlhUzJ5WDFkOCIsIm5hbWUiOiJva3RhcHJveHkgb2t0YXByb3h5IiwidmVyIjoxLCJpc3MiOiJodHRwczovL2NvbXBhbnl4Lm9rdGEuY29tIiwiYXVkIjoidlpWNkNwOHJuNWx4ck45YVo2ODgiLCJpYXQiOjE0ODEzODg0NTMsImV4cCI6MTQ4MTM5MjA1MywianRpIjoiSUQuWm9QdVdIR3IxNkR6a3RUbEdXMFI4b1lRaUhnVWg0aUotTHo3Z3BGcGItUSIsImFtciI6WyJwd2QiXSwiaWRwIjoiMDBveTc0YzBnd0hOWE1SSkJGUkkiLCJub25jZSI6Im4tMFM2X1d6QTJNaiIsInByZWZlcnJlZF91c2VybmFtZSI6Im9rdGFwcm94eUBva3RhLmNvbSIsImF1dGhfdGltZSI6MTQ4MTM4ODQ0MywiYXRfaGFzaCI6Im1YWlQtZjJJczhOQklIcV9CeE1ISFEifQ.OtVyCK0sE6Cuclg9VMD2AwLhqEyq2nv3a1bfxlzeS-bdu9KtYxcPSxJ6vxMcSSbMIIq9eEz9JFMU80zqgDPHBCjlOsC5SIPz7mm1Z3gCwq4zsFJ-2NIzYxA3p161ZRsPv_3bUyg9B_DPFyBoihgwWm6yrvrb4rmHXrDkjxpxCLPp3OeIpc_kb2t8r5HEQ5UBZPrsiScvuoVW13YwWpze59qBl_84n9xdmQ5pS7DklzkAVgqJT_NWBlb5uo6eW26HtJwHzss7xOIdQtcOtC1Gj3O82a55VJSQnsEEBeqG1ESb5Haq_hJgxYQnBssKydPCIxdZiye-0Ll9L8wWwpzwig 

Here are the Keys:

{    "keys":[       {          "alg":"RS256",          "e":"AQAB",          "n":"ok6rvXu95337IxsDXrKzlIqw_I_zPDG8JyEw2CTOtNMoDi1QzpXQVMGj2snNEmvNYaCTmFf51I-EDgeFLLexr40jzBXlg72quV4aw4yiNuxkigW0gMA92OmaT2jMRIdDZM8mVokoxyPfLub2YnXHFq0XuUUgkX_TlutVhgGbyPN0M12teYZtMYo2AUzIRggONhHvnibHP0CPWDjCwSfp3On1Recn4DPxbn3DuGslF2myalmCtkujNcrhHLhwYPP-yZFb8e0XSNTcQvXaQxAqmnWH6NXcOtaeWMQe43PNTAyNinhndgI8ozG3Hz-1NzHssDH_yk6UYFSszhDbWAzyqw",          "kid":"wyMwK4A6CL9Qw11uofVeyQ119XyX-xykymkkXygZ5OM",          "kty":"RSA",          "use":"sig"       },       {          "alg":"RS256",          "e":"AQAB",          "n":"nXv6FSAcMjuanQ2hIIUb8Vkqe94t98kPh2T8-0j6-Jq8pOclgKdtVeIZcBE9F_XiuJvg4b6WVs-uvA-pS8mmMvQ21xU5Q_37Cojv8v_QlHWETHwEJdXXiY2Xq5LgXDSwEhhdDZHSMQYDuvhp_P6nl2LNqqUvJkjoFWcnn2btgSIUQROIaDdxtx7_2h4oUi5u11BGSF2SZZiEpDAKT08Htv3uwXdwDA6ll99fbi8X8RmH5oY_tIZTeIzu50qHxElPewoYO8QrJYsO9oFcCPMHGxYWjXQEa-QZYgo0wS9zRIkeJc5kshc4-9Uhv2DVIjk_-ofGlML9ieggGyillBKptw",          "kid":"GRF55Lbzgg4sANCmER-sm55eX_qUOpY8UTptDmDG_6U",          "kty":"RSA",          "use":"sig"       }    ] } 
like image 720
user3888307 Avatar asked Dec 10 '16 16:12

user3888307


People also ask

What is this JWT verifier for go?

This package is a JWT signer, verifier and validator for Go (or Golang). Although there are many JWT packages out there for Go, many lack support for some signing, verifying or validation methods and, when they don't, they're overcomplicated.

Is it possible to parse JWT token using JWT-go?

To receive the JWT token, in a RS256 format. I am now struggling to validate, and parse the token in Golang. I’ve tried to parse it using jwt-go, but it appears to support HMAC instead by default and read somewhere that they recommend using frontend validation instead. I tried a few other packages and had similar problems.

How do I create a JWT authentication API in Golang?

+ Now that we have a better idea about JWTs, let’s create our small authentication API in Golang. Create a new directory in your GOPATH, call it authapp, and then initiate a Go module. To make it simple to follow along, I’m going to use an SQLite database.

How does JWT work in web API?

The client will log the user in by sending the credentials to the API server. The API server will validate the user credentials, sign a JWT, and return it in the HTTP response. The client will use the received JWT to access API resources. The API server will validate the JWT and authorize the user to access the resource. What Is JWT?


1 Answers

Below is an example of JWT decoding and verification. It uses both the jwt-go and jwk packages:

package main  import (     "errors"     "fmt"      "github.com/dgrijalva/jwt-go"     "github.com/lestrrat-go/jwx/jwk" )  const token = `eyJhbGciOiJSUzI1NiIsImtpZCI6Ind5TXdLNEE2Q0w5UXcxMXVvZlZleVExMTlYeVgteHlreW1ra1h5Z1o1T00ifQ.eyJzdWIiOiIwMHUxOGVlaHUzNDlhUzJ5WDFkOCIsIm5hbWUiOiJva3RhcHJveHkgb2t0YXByb3h5IiwidmVyIjoxLCJpc3MiOiJodHRwczovL2NvbXBhbnl4Lm9rdGEuY29tIiwiYXVkIjoidlpWNkNwOHJuNWx4ck45YVo2ODgiLCJpYXQiOjE0ODEzODg0NTMsImV4cCI6MTQ4MTM5MjA1MywianRpIjoiSUQuWm9QdVdIR3IxNkR6a3RUbEdXMFI4b1lRaUhnVWg0aUotTHo3Z3BGcGItUSIsImFtciI6WyJwd2QiXSwiaWRwIjoiMDBveTc0YzBnd0hOWE1SSkJGUkkiLCJub25jZSI6Im4tMFM2X1d6QTJNaiIsInByZWZlcnJlZF91c2VybmFtZSI6Im9rdGFwcm94eUBva3RhLmNvbSIsImF1dGhfdGltZSI6MTQ4MTM4ODQ0MywiYXRfaGFzaCI6Im1YWlQtZjJJczhOQklIcV9CeE1ISFEifQ.OtVyCK0sE6Cuclg9VMD2AwLhqEyq2nv3a1bfxlzeS-bdu9KtYxcPSxJ6vxMcSSbMIIq9eEz9JFMU80zqgDPHBCjlOsC5SIPz7mm1Z3gCwq4zsFJ-2NIzYxA3p161ZRsPv_3bUyg9B_DPFyBoihgwWm6yrvrb4rmHXrDkjxpxCLPp3OeIpc_kb2t8r5HEQ5UBZPrsiScvuoVW13YwWpze59qBl_84n9xdmQ5pS7DklzkAVgqJT_NWBlb5uo6eW26HtJwHzss7xOIdQtcOtC1Gj3O82a55VJSQnsEEBeqG1ESb5Haq_hJgxYQnBssKydPCIxdZiye-0Ll9L8wWwpzwig`  const jwksURL = `https://companyx.okta.com/oauth2/v1/keys`  func getKey(token *jwt.Token) (interface{}, error) {      // TODO: cache response so we don't have to make a request every time     // we want to verify a JWT     set, err := jwk.FetchHTTP(jwksURL)     if err != nil {         return nil, err     }      keyID, ok := token.Header["kid"].(string)     if !ok {         return nil, errors.New("expecting JWT header to have string kid")     }      if key := set.LookupKeyID(keyID); len(key) == 1 {         return key[0].Materialize()     }      return nil, fmt.Errorf("unable to find key %q", keyID) }  func main() {     token, err := jwt.Parse(token, getKey)     if err != nil {         panic(err)     }     claims := token.Claims.(jwt.MapClaims)     for key, value := range claims {         fmt.Printf("%s\t%v\n", key, value)     } } 
like image 100
Tim Cooper Avatar answered Oct 01 '22 14:10

Tim Cooper