msauth

package
v0.1.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 2, 2020 License: Apache-2.0 Imports: 15 Imported by: 17

README

msauth

Introduction

Very simple package to authorize applications against Microsoft identity platform.

It utilizes v2.0 endpoint so that it can authorize users using both personal (Microsoft) and organizational (Azure AD) account.

Usage

Device authorization grant
const (
	tenantID     = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
	clientID     = "YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY"
	tokenCachePath  = "token_cache.json"
)

var scopes = []string{"openid", "profile", "offline_access", "User.Read", "Files.Read"}

	ctx := context.Background()
	m := msauth.NewManager()
	m.LoadFile(tokenCachePath)
	ts, err := m.DeviceAuthorizationGrant(ctx, tenantID, clientID, scopes, nil)
	if err != nil {
		log.Fatal(err)
	}
	m.SaveFile(tokenCachePath)

	httpClient := oauth2.NewClient(ctx, ts)
	...
Client credentials grant
const (
	tenantID     = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
	clientID     = "YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY"
	clientSecret = "ZZZZZZZZZZZZZZZZZZZZZZZZ"
)

var scopes = []string{msauth.DefaultMSGraphScope}

	ctx := context.Background()
	m := msauth.NewManager()
	ts, err := m.ClientCredentialsGrant(ctx, tenantID, clientID, clientSecret, scopes)
	if err != nil {
		log.Fatal(err)
	}

	httpClient := oauth2.NewClient(ctx, ts)
    ...
Resource owner password credentials grant
const (
	tenantID     = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
	clientID     = "YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY"
	clientSecret = "ZZZZZZZZZZZZZZZZZZZZZZZZ"
	username     = "user.name@your-domain.com"
	password     = "secure-password"
)

var scopes = []string{msauth.DefaultMSGraphScope}

	ctx := context.Background()
	m := msauth.NewManager()
	ts, err := m.ResourceOwnerPasswordGrant(ctx, tenantID, clientID, clientSecret, username, password, scopes)
	if err != nil {
		log.Fatal(err)
	}

	httpClient := oauth2.NewClient(ctx, ts)
    ...
Authorization code grant

Documentation

Overview

Package msauth implements a library to authorize against Microsoft identity platform: https://docs.microsoft.com/en-us/azure/active-directory/develop/

It utilizes v2.0 endpoint so it can authorize users with both personal (Microsoft) and organizational (Azure AD) account.

Index

Examples

Constants

View Source
const (
	// DefaultMSGraphScope is the default scope for MS Graph API
	DefaultMSGraphScope = "https://graph.microsoft.com/.default"
)

Variables

This section is empty.

Functions

func CacheKey added in v0.1.3

func CacheKey(tenantID, clientID string) string

CacheKey generates a token cache key from tenantID/clientID

func ReadLocation added in v0.1.3

func ReadLocation(loc string) ([]byte, error)

ReadLocation reads data from file with path or URL

func WriteLocation added in v0.1.3

func WriteLocation(loc string, b []byte, m os.FileMode) error

WriteLocation writes data to file with path or URL

Types

type DeviceCode

type DeviceCode struct {
	DeviceCode      string `json:"device_code"`
	UserCode        string `json:"user_code"`
	VerificationURL string `json:"verification_url"`
	ExpiresIn       int    `json:"expires_in"`
	Interval        int    `json:"interval"`
	Message         string `json:"message"`
}

DeviceCode is returned on device auth initiation

type Manager

type Manager struct {
	Dirty      bool
	TokenCache map[string]*oauth2.Token
	// contains filtered or unexported fields
}

Manager is oauth2 token cache manager

func NewManager

func NewManager() *Manager

NewManager returns a new Manager instance

func (*Manager) ClientCredentialsGrant

func (m *Manager) ClientCredentialsGrant(ctx context.Context, tenantID, clientID, clientSecret string, scopes []string) (oauth2.TokenSource, error)

ClientCredentialsGrant performs OAuth 2.0 client credentials grant and returns auto-refreshing TokenSource

Example
package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"

	"github.com/yaegashi/msgraph.go/msauth"
	"golang.org/x/oauth2"
)

const (
	tenantID     = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
	clientID     = "YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY"
	clientSecret = "ZZZZZZZZZZZZZZZZZZZZZZZZ"
)

var ccScopes = []string{msauth.DefaultMSGraphScope}

func main() {
	ctx := context.Background()
	m := msauth.NewManager()
	ts, err := m.ClientCredentialsGrant(ctx, tenantID, clientID, clientSecret, ccScopes)
	if err != nil {
		log.Fatal(err)
	}
	httpClient := oauth2.NewClient(ctx, ts)
	res, err := httpClient.Get("https://graph.microsoft.com/v1.0/me")
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()
	b, err := ioutil.ReadAll(res.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", string(string(b)))
}
Output:

func (*Manager) DeviceAuthorizationGrant

func (m *Manager) DeviceAuthorizationGrant(ctx context.Context, tenantID, clientID string, scopes []string, callback func(*DeviceCode) error) (oauth2.TokenSource, error)

DeviceAuthorizationGrant performs OAuth 2.0 device authorization grant and returns auto-refreshing TokenSource

Example
package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"

	"github.com/yaegashi/msgraph.go/msauth"
	"golang.org/x/oauth2"
)

const (
	tenantID = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
	clientID = "YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY"

	tokenStorePath = "token_store.json"
)

var daScopes = []string{"openid", "profile", "offline_access", "User.Read", "Files.Read"}

func main() {
	ctx := context.Background()
	m := msauth.NewManager()
	m.LoadFile(tokenStorePath)
	ts, err := m.DeviceAuthorizationGrant(ctx, tenantID, clientID, daScopes, nil)
	if err != nil {
		log.Fatal(err)
	}
	err = m.SaveFile(tokenStorePath)
	if err != nil {
		log.Fatal(err)
	}
	httpClient := oauth2.NewClient(ctx, ts)
	res, err := httpClient.Get("https://graph.microsoft.com/v1.0/me")
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()
	b, err := ioutil.ReadAll(res.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", string(string(b)))
}
Output:

func (*Manager) GetToken added in v0.1.3

func (m *Manager) GetToken(cacheKey string) (*oauth2.Token, bool)

GetToken gets a token from token cache

func (*Manager) LoadBytes

func (m *Manager) LoadBytes(b []byte) error

LoadBytes loads token cache from opaque bytes (it's actually JSON)

func (*Manager) LoadFile

func (m *Manager) LoadFile(path string) error

LoadFile loads token cache from file with dirty state control

func (*Manager) PutToken added in v0.1.3

func (m *Manager) PutToken(cacheKey string, token *oauth2.Token)

PutToken puts a token into token cache

func (*Manager) ResourceOwnerPasswordGrant added in v0.1.3

func (m *Manager) ResourceOwnerPasswordGrant(ctx context.Context, tenantID, clientID, clientSecret, username, password string, scopes []string) (oauth2.TokenSource, error)

ResourceOwnerPasswordGrant preforms OAuth 2.0 client resource owner password grant and returns a token.

Example
package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"

	"github.com/yaegashi/msgraph.go/msauth"
	"golang.org/x/oauth2"
)

const (
	tenantID     = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
	clientID     = "YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY"
	clientSecret = "ZZZZZZZZZZZZZZZZZZZZZZZZ"
	username     = "user.name@your-domain.com"
	password     = "secure-password"
)

var ccScopes = []string{msauth.DefaultMSGraphScope}

func main() {
	ctx := context.Background()
	m := msauth.NewManager()
	ts, err := m.ResourceOwnerPasswordGrant(ctx, tenantID, clientID, clientSecret, username, password, ccScopes)
	if err != nil {
		log.Fatal(err)
	}
	httpClient := oauth2.NewClient(ctx, ts)
	res, err := httpClient.Get("https://graph.microsoft.com/v1.0/me")
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()
	b, err := ioutil.ReadAll(res.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", string(string(b)))
}
Output:

func (*Manager) SaveBytes

func (m *Manager) SaveBytes() ([]byte, error)

SaveBytes saves token cache to opaque bytes (it's actually JSON)

func (*Manager) SaveFile

func (m *Manager) SaveFile(path string) error

SaveFile saves token cache to file with dirty state control

type TokenError

type TokenError struct {
	ErrorObject      string `json:"error"`
	ErrorDescription string `json:"error_description"`
}

TokenError is returned on failed authentication

func (*TokenError) Error

func (t *TokenError) Error() string

Error implements error interface

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL