-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 3d4698f
Showing
10 changed files
with
352 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/bin | ||
/.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# ms-graph-auth-helper | ||
|
||
一个可以快速帮助获取Microsoft Graph API(OneDriver)令牌的小工具 | ||
|
||
~~在弄网盘API的时候觉得太麻烦了就搞了个这个~~ | ||
|
||
![ms-auth-run](https://user-images.githubusercontent.com/7535224/147150440-a5074cc7-ce73-4663-b9ee-09a323949666.png) | ||
|
||
## 如何使用 | ||
|
||
在获取令牌时,请按照以下步骤操作 | ||
|
||
#### 注册新应用 | ||
|
||
- 打开[Azure应用管理面板](https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade)注册新的应用 | ||
|
||
- **受支持的帐户类型** 选项选择 **任何组织目录(任何 Azure AD 目录 - 多租户)中的帐户和个人 Microsoft 帐户(例如,Skype、Xbox)** | ||
|
||
- 重定向URL(可选)中选择 **Web** 类型并将URL值设置为 **`http://localhost:11451/auth`** | ||
|
||
#### 权限 | ||
|
||
- 切换至 **API权限** 选项卡点击 **添加权限** | ||
|
||
- 选择 **Microsoft Graph** 分类 | ||
|
||
- 使用搜索功能找到并勾选以下权限: | ||
|
||
- Files.Read | ||
|
||
- Files.Read.All | ||
|
||
- Files.ReadWrite | ||
|
||
- Files.ReadWrite.All | ||
|
||
- offline_access | ||
|
||
- 点击 **添加权限** 完成授权 | ||
|
||
#### 应用程序(客户端) ID [Client Id] | ||
|
||
- 切换至 **概述** 选项卡复制**应用程序(客户端) ID** 并**自行保管** | ||
|
||
#### 机密值[Client Secret] | ||
|
||
- 切换至 **证书和密码** 选项卡 | ||
|
||
- 点击 **新建客户端密码** 并创建一个新的密钥 | ||
|
||
- 创建完成后复制密钥的值并**自行保管** | ||
|
||
#### 启动工具按照提示完成令牌的获取 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package main | ||
|
||
import ( | ||
"os/exec" | ||
) | ||
|
||
func OpenBrowser(path string) error { | ||
err := exec.Command("rundll32", "url.dll,FileProtocolHandler", path).Start() | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
module ms-graph-auth-helper | ||
|
||
go 1.17 | ||
|
||
require github.com/gin-gonic/gin v1.7.7 | ||
|
||
require ( | ||
github.com/gin-contrib/sse v0.1.0 // indirect | ||
github.com/go-playground/locales v0.13.0 // indirect | ||
github.com/go-playground/universal-translator v0.17.0 // indirect | ||
github.com/go-playground/validator/v10 v10.4.1 // indirect | ||
github.com/golang/protobuf v1.3.3 // indirect | ||
github.com/json-iterator/go v1.1.9 // indirect | ||
github.com/leodido/go-urn v1.2.0 // indirect | ||
github.com/mattn/go-isatty v0.0.12 // indirect | ||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect | ||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect | ||
github.com/ugorji/go/codec v1.1.7 // indirect | ||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect | ||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect | ||
gopkg.in/yaml.v2 v2.2.8 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= | ||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= | ||
github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= | ||
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= | ||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= | ||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= | ||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= | ||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= | ||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= | ||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= | ||
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= | ||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= | ||
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= | ||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= | ||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= | ||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | ||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= | ||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= | ||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= | ||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= | ||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= | ||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= | ||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= | ||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | ||
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= | ||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= | ||
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= | ||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= | ||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= | ||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= | ||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | ||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= | ||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"os" | ||
"strings" | ||
"time" | ||
) | ||
|
||
var console = bufio.NewReader(os.Stdin) | ||
|
||
func main() { | ||
initLog() | ||
//重定向服务器 | ||
go StartServer() | ||
fmt.Println("将跳转浏览器授权") | ||
fmt.Println("请输入App的应用程序(客户端) ID [Client Id]") | ||
clientId := readLine() | ||
err := OpenBrowser(BuildMsAuthorizeUrl(clientId)) | ||
if err != nil { | ||
fmt.Printf("启动浏览器时发生错误\r\n%s", err.Error()) | ||
} | ||
fmt.Println() | ||
clientCode := <-CodeCh | ||
if clientCode != nil { | ||
fmt.Printf("获取到code(%v)\r\n", len(*clientCode)) | ||
} else { | ||
fmt.Println("获取code失败,请检查client_id和网络设置") | ||
_ = readLine() | ||
return | ||
} | ||
fmt.Println() | ||
fmt.Println("请输入App的机密值[Client Secret]") | ||
clientSecret := readLine() | ||
fmt.Println() | ||
tokenData, err := MsTokenRequest(clientId, clientSecret, *clientCode) | ||
if err != nil { | ||
fmt.Printf("获取token时发生错误\r\n%s", err.Error()) | ||
} | ||
fmt.Printf("获取到token(%v)\r\n", len(tokenData.AccessToken)) | ||
fmt.Printf("获取到refresh-token(%v)\r\n", len(tokenData.RefreshToken)) | ||
saveData := TokenResult{ | ||
ClientId: clientId, | ||
ClientCode: *clientCode, | ||
Secret: clientSecret, | ||
AccessToken: tokenData.AccessToken, | ||
RefreshToken: tokenData.RefreshToken, | ||
} | ||
jsonBytes, err := saveData.Save() | ||
if err != nil { | ||
fmt.Println("保存token信息失败,请自行复制获取到的token") | ||
time.Sleep(time.Second * 3) | ||
fmt.Println(string(*jsonBytes)) | ||
}else{ | ||
fmt.Println("token信息已保存至工具根目录的result.json文件中") | ||
} | ||
fmt.Println("按下回车退出本工具") | ||
readLine() | ||
} | ||
|
||
func readLine() (str string) { | ||
str, _ = console.ReadString('\n') | ||
str = strings.TrimSpace(str) | ||
return | ||
} | ||
|
||
func initLog() { | ||
fmt.Println("Ciallo~(∠・ω< )⌒☆") | ||
fmt.Println("本工具将帮助你获取微软Graph的API的访问令牌,获取到的结果将保存到工具运行的目录下") | ||
fmt.Println() | ||
fmt.Println("请先保证使用本工具前已经在Microsoft Azure重创建了新的应用,并满足以下条件:") | ||
fmt.Println("1.并授予了offline_access Files.Read Files.Read.All Files.ReadWrite Files.ReadWrite.All权限") | ||
fmt.Println("2.重定向URL选择了(Web)类型,并设置值为(http://localhost:11451/auth)") | ||
fmt.Println("3.在证书和密码选项卡中创建并保存了机密值(Client Secret)") | ||
fmt.Println("请在确认以上条件后按回车继续") | ||
_ = readLine() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package main | ||
|
||
type TokenResp struct { | ||
TokenType string `json:"token_type"` | ||
Scope string `json:"scope"` | ||
ExpiresIn int `json:"expires_in"` | ||
ExtExpiresIn int `json:"ext_expires_in"` | ||
AccessToken string `json:"access_token"` | ||
RefreshToken string `json:"refresh_token"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/gin-gonic/gin" | ||
) | ||
|
||
// CodeCh 用于传输服务器返回的client-code | ||
var CodeCh = make(chan *string) | ||
|
||
func StartServer() { | ||
gin.SetMode(gin.ReleaseMode) | ||
router := gin.New() | ||
router.GET("/auth", authMs) | ||
err := router.Run(":11451") | ||
if err != nil { | ||
return | ||
} | ||
} | ||
|
||
func authMs(c *gin.Context) { | ||
code := c.Query("code") | ||
if len(code) != 0 { | ||
CodeCh <- &code | ||
c.String(200, "获取client-code成功,请回到工具执行下一步操作\r\n\r\n%s" , code) | ||
}else{ | ||
CodeCh <- nil | ||
c.String(200, "获取client-code失败,请检查网络设置并再次运行") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"os" | ||
) | ||
|
||
type TokenResult struct { | ||
ClientId string `json:"client-id"` | ||
ClientCode string `json:"client-code"` | ||
Secret string `json:"secret"` | ||
AccessToken string `json:"access-token"` | ||
RefreshToken string `json:"refresh-token"` | ||
} | ||
|
||
func (res *TokenResult) Save() (*[]byte, error) { | ||
file, err := os.Create("result.json") | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer func(file *os.File) { | ||
_ = file.Close() | ||
}(file) | ||
if err != nil { | ||
return nil, err | ||
} | ||
jsonBytes, err := json.MarshalIndent(res, ""," ") | ||
if err != nil { | ||
return nil, err | ||
} | ||
_, err = file.Write(jsonBytes) | ||
return &jsonBytes, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"net/http" | ||
"net/url" | ||
"strings" | ||
) | ||
|
||
func BuildMsAuthorizeUrl(clientId string) string { | ||
u, _ := url.Parse("https://login.microsoftonline.com/common/oauth2/v2.0/authorize") | ||
urlQuery := u.Query() | ||
urlQuery.Set("client_id", clientId) | ||
urlQuery.Set("redirect_uri", "http://localhost:11451/auth") | ||
urlQuery.Set("response_type", "code") | ||
u.RawQuery = urlQuery.Encode() | ||
return fmt.Sprintf("%s&scope=offline_access+Files.Read+Files.Read.All+Files.ReadWrite+Files.ReadWrite.All", u.String()) | ||
} | ||
|
||
func MsTokenRequest(clientId, clientSecret, clientCode string) (*TokenResp, error) { | ||
data := url.Values{} | ||
data.Set("client_id", clientId) | ||
data.Set("redirect_uri", "http://localhost:11451/auth") | ||
data.Set("client_secret", clientSecret) | ||
data.Set("code", clientCode) | ||
data.Set("grant_type", "authorization_code") | ||
r, err := http.NewRequest(http.MethodPost, | ||
"https://login.microsoftonline.com/common/oauth2/v2.0/token", | ||
strings.NewReader(data.Encode())) | ||
if err != nil { | ||
return nil, err | ||
} | ||
r.Header.Add("Content-Type", "application/x-www-form-urlencoded") | ||
client := &http.Client{} | ||
resp, err := client.Do(r) | ||
if resp.StatusCode != http.StatusOK { | ||
errInfo := fmt.Sprintf("response http code %v", resp.StatusCode) | ||
return nil, errors.New(errInfo) | ||
} | ||
defer func(Body io.ReadCloser) { | ||
_ = Body.Close() | ||
}(resp.Body) | ||
body, err := ioutil.ReadAll(resp.Body) | ||
if err != nil { | ||
return nil, err | ||
} | ||
tokenData := TokenResp{} | ||
err = json.Unmarshal(body, &tokenData) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &tokenData, nil | ||
} |