Getting API access tokens with Golang
I am using Golang to work with the Box API. However, I am trying to generate access tokens through the method of using JWT to eliminate the need for user interaction beyond initial setup. However, after creating a JWT and trying to send it in an oAuth request, I am failing to retrieve an access token. The following to functions create a JWT to use in an oAuth request to gain an access token. However, the response body is empty and the HTTP request generates a 400 (Bad Request) error. After the functions I show the result of printing out the resp.Status and resp.Body
// JWTAUTHURL - URL for oAUTH for Box const JWTAUTHURL string = "https://api.box.com/oauth2/token" // JWTGRANTTYPE - mandatory parameter for box oAuth const JWTGRANTTYPE string = "urn:ietf:params:oauth:grant-type:jwt-bearer" // oAuthResponse holds decoded JSON response from Box type oAuthResponse struct { AccessToken string `json:"access_token"` Expires int `json:"expires_in"` RestrictedTo []string `json:"restricted_to"` TokenType string `json:"token_type"` } // CreateJWTAssertion - build up the JSON Web Token for oAuth func CreateJWTAssertion(PublicKeyID string, ClientID string, Sub string, user *AppUserResponse) (string, error) { var signingKey []byte var err error var msg, tokenString string signingKey, err = ioutil.ReadFile("private_key.pem") if err != nil { msg = "Unable to read signing key. Please ensure your private signing key is in the ./keys/ directory" return msg, err } // Generate JTI Value jti, err := exec.Command("uuidgen").Output() if err != nil { msg = "Unable to generate JTI value" return msg, err } token := jwt.New(jwt.SigningMethodHS256) claims := make(jwt.MapClaims) token.Header["alg"] = "HS256" token.Header["typ"] = "JWT" token.Header["kid"] = PublicKeyID claims["iss"] = ClientID claims["aud"] = JWTAUTHURL claims["jti"] = jti claims["exp"] = time.Now().Add(time.Second * 45).Unix() // Create the JWT either for the enterprise or for a specific user. if user.ID != "" { claims["box_sub_type"] = "user" claims["sub"] = user.ID } else { claims["box_sub_type"] = "enterprise" claims["sub"] = Sub } token.Claims = claims // Sign the JWT tokenString, err = token.SignedString(signingKey) if err != nil { msg = "Unable to sign token, please check that you have a signing key in ./keys/" return msg, err } return tokenString, err } // SendOAuthRequest - Sends a POST to authenticate against Box using JWT Assertion func SendOAuthRequest(ClientID string, ClientSecret string, JWToken string) (string, error) { var err error var msg string var decodedResponse *oAuthResponse hc := http.Client{} form := url.Values{} // Build form to POST form.Add("grant_type", JWTGRANTTYPE) form.Add("client_id", ClientID) form.Add("client_secret", ClientSecret) form.Add("assertion", JWToken) // Here is where the code stops working, returns an empty body // The request looks like it should be working req, err := http.NewRequest("POST", JWTAUTHURL, strings.NewReader(form.Encode())) req.PostForm = form req.Header.Add("Content-Type", "application/x-www-form-urlencoded") if err != nil { return msg, err } resp, err := hc.Do(req) if err != nil { msg = "Error submitting request to Box API" return msg, err } // fmt.Println(resp.Status) fmt.Println(resp.Body) // err = json.NewDecoder(resp.Body).Decode(&decodedResponse) if err != nil { msg = "Error decoding OAuthResponse" } else { // We only need the Access Token msg = decodedResponse.AccessToken } return msg, err }
400 Bad Request &{0xc420064100 {0 0} false 0x5f48b0 0x5f4840}
-
Per the JWT authentication documentation, the Box API does not currently support the HS256 JWT signature algorithm that you're using. Could you try changing to RS256 instead and see if that works?
-
I'm sure this is extremely late, but I'm just working through this now.
So, you're failing on the
/oauth2/token
request? I'm actually getting the token back. (My problem is that I'm getting failures when I use it.)
Why are you passing the body as a string? Create a bytes.NewReader.
Please sign in to leave a comment.
Comments
3 comments