2016-12-10 52 views
3

我一直在尋找一個例子,我可以理解如何使用GO語言驗證JWT的簽名。去語言和驗證JWT

這可能是特別棘手的,因爲我使用Okta,它使用JWKs,所以它不是特別直截了當。

當我收到JWT時,我可以解碼它沒有問題,只是卡在如何驗證簽名。

下面我列出了JWT和JWK的細節。如果有人對此感到滿意,並且可以使用示例完成簽名驗證,那將會很棒。:)

您可以在此處獲得所有此信息:https://oktaproxy.com/oidcgenerator.php,此站點將從Okta生成JWT,並且鑰匙可以在這裏獲得:https://companyx.okta.com/oauth2/v1/keys

這裏是JWT:

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

下面是鍵:

{ 
    "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" 
     } 
    ] 
} 

回答

5

下面是JWT解碼和驗證的一個例子。它同時使用jwt-gojwk程序包:

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, errors.New("unable to find key") 
} 

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) 
    } 
} 
+0

工作正常!我將代碼放在GO Playground上,以便其他人可以看到代碼。 https://play.golang.org/p/fkag0DMexY – user3888307