使用Go语言通过REST API进行Azure身份验证

huangapple go评论103阅读模式
英文:

Authenticating to Azure in Go using REST API

问题

我正在尝试使用golang对Azure服务管理/图形API进行身份验证。
只使用纯粹的REST API。
无论我做什么,我总是遇到错误:

{"error":"invalid_request","error_description":"AADSTS900144: The request body must contain the following parameter: 'grant_type'."}

由于我没有使用SDK,所以现有的示例有限。任何帮助将不胜感激。

package main

import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
)

func main() {

	authendpoint := "https://login.microsoftonline.com/8xxxxx7-6372-4bcb-xxx-xxxxxx/oauth2/token"

	jsonData := []byte(`{
		"resource":      "https://graph.microsoft.com",
		"client_id":     "xxxxxxxx-7549-4ea2-b00d-xxxxxxxxxxx",
		"client_secret": "Q.xxxxxxxxxxxxxx-6_CgA4yOi_8sS-",
		"grant_type":    "client_credentials",
		}`)

	request, err := http.NewRequest("POST", authendpoint, bytes.NewBuffer(jsonData))
	request.Header.Set("Content-Type", "application/json")
	client := &http.Client{}
	resp, err := client.Do(request)

	if err != nil {
		log.Fatal(err)
	}
	body, err := ioutil.ReadAll(resp.Body)
	var res map[string]interface{}

	json.NewDecoder(resp.Body).Decode(&res)
	log.Println(string(body))
}
英文:

I am trying to authenticate to Azure service management / graph API using golang.
Using purely REST APIs.
No matter what I do, I always end up with error:

{"error":"invalid_request","error_description":"AADSTS900144: The request body must contain the following parameter: 'grant_type'.

Since I am not using SDK there is limited samples out there. Any help would be appreciated.

package main

import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
)

func main() {

	authendpoint := "https://login.microsoftonline.com/8xxxxx7-6372-4bcb-xxx-xxxxxx/oauth2/token"

	jsonData := []byte(`{
		"resource":      "https://graph.microsoft.com",
		"client_id":     "xxxxxxxx-7549-4ea2-b00d-xxxxxxxxxxx",
		"client_secret": "Q.xxxxxxxxxxxxxx-6_CgA4yOi_8sS-",
		"grant_type":    "client_credentials",
		}`)

	request, err := http.NewRequest("POST", authendpoint, bytes.NewBuffer(jsonData))
	request.Header.Set("Content-Type", "application/json")
	client := &http.Client{}
	resp, err := client.Do(request)

	if err != nil {
		log.Fatal(err)
	}
	body, err := ioutil.ReadAll(resp.Body)
	var res map[string]interface{}

	json.NewDecoder(resp.Body).Decode(&res)
	log.Println(string(body))
}

答案1

得分: 2

Praveen Premaratne发布的Microsoft请求文档显示,请求需要使用Content-Type: application/x-www-form-urlencoded进行格式化,这是OAuth 2.0标准的要求。

以下是Microsoft文档和示例:

https://learn.microsoft.com/en-us/graph/auth/auth-concepts#register-your-app-with-the-microsoft-identity-platform

package main

import (
	"fmt"
	"net/http"
	"net/url"
    "strings"
)

func main() {
	authendpoint := "https://login.microsoftonline.com/8xxxxx7-6372-4bcb-xxx-xxxxxx/oauth2/token"
	body := url.Values(map[string][]string{
		"resource":      {"https://graph.microsoft.com"},
		"client_id":     {"xxxxxxxx-7549-4ea2-b00d-xxxxxxxxxxx"},
		"client_secret": {"Q.xxxxxxxxxxxxxx-6_CgA4yOi_8sS-"},
		"grant_type":    {"client_credentials"}})

	request, err := http.NewRequest(
		http.MethodPost,
		authendpoint,
		strings.NewReader(body.Encode()))
	if err != nil {
		panic(err)
	}

	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	client := &http.Client{}
	resp, err := client.Do(request)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.StatusCode)
}

要完成此操作,请按照以下步骤进行操作。

英文:

The Microsoft request docs posted by Praveen Premaratne show the request needs to be formatted using Content-Type: application/x-www-form-urlencoded which is a requirement for the OAuth 2.0 standard.

Here's the Microsoft docs and example:

https://learn.microsoft.com/en-us/graph/auth/auth-concepts#register-your-app-with-the-microsoft-identity-platform

POST /common/oauth2/v2.0/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&scope=user.read%20mail.read
&code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr...
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&grant_type=authorization_code
&client_secret=JqQX2PNo9bpM0uEihUPzyrh  

Here's how to accomplish this:

package main

import (
	"fmt"
	"net/http"
	"net/url"
    "strings"
)

func main() {
	authendpoint := "https://login.microsoftonline.com/8xxxxx7-6372-4bcb-xxx-xxxxxx/oauth2/token"
	body := url.Values(map[string][]string{
		"resource":      {"https://graph.microsoft.com"},
		"client_id":     {"xxxxxxxx-7549-4ea2-b00d-xxxxxxxxxxx"},
		"client_secret": {"Q.xxxxxxxxxxxxxx-6_CgA4yOi_8sS-"},
		"grant_type":    {"client_credentials"}})

	request, err := http.NewRequest(
		http.MethodPost,
		authendpoint,
		strings.NewReader(body.Encode()))
	if err != nil {
		panic(err)
	}

	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	client := &http.Client{}
	resp, err := client.Do(request)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.StatusCode)
}

答案2

得分: 0

对我来说,当我从请求体中删除resource并在请求体中添加scope作为新参数时,它起作用了。

英文:

for me, it worked when I removed resource from the request body and added scope as new parameter in body.

huangapple
  • 本文由 发表于 2021年7月20日 05:42:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/68447348.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定