marstore

package module
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Aug 11, 2024 License: MIT Imports: 13 Imported by: 0

README

Logo

Purpose of the 'marstore' package

Go Reference

marstore stands for m365, authentication, redis, and (redis)-store. This package helps business developers authenticate their users against M365 (business and university) accounts. This package helps with authenticating M365 / Entra services in the Go language.

Developers interested in standard Microsoft online authentication or Azure accounts can try the Goth package: https://github.com/markbates/goth

Technical documentation

Details can be found here: https://pkg.go.dev/github.com/jeannot-muller/marstore#pkg-overview

Prerequisites
  • A working Redis server for both development and production (required).

  • Go-Chi router (recommended).

  • A working application in a Microsoft Tenant (required).

  • The credentials for that app and properly set URLs for callbacks and logout functionality (required).

  • A working internet connection and open firewalls to ensure Microsoft authentication services can be reached.

Participation

Feel free to fork the repo, suggest changes, or raise issues. Please use the original GitHub repository to do so.

How-Tos

Use of the library in your own code

Microsoft OAuth authentication workflow follows a logical and simple path:

  1. First, the user needs to log in. The example code here doesn't show a login button, as everyone will follow their own logic. But you can just enter the login path manually into your app.

  2. We need a '/login' handler (or any other path you specify) which will forward the request to Microsoft for authentication.

  3. Microsoft will call back (with a token) the URL you specified in the properties of the application in your tenant and reflected 1:1 in the configuration structure of your app.

  4. The library will store the token and the User structure from Microsoft in a Redis store in the background and write a secure cookie in the browser of the user who made the request.

Installing a Redis Server Locally or in Production

This page https://redis.io/docs/latest/get-started/ provides details on how to install the free community edition of Redis on either your development or production system. Overall, this is a straightforward process. Redis Insight is a small desktop app that can help you monitor and check your Redis installation.

Configuring a Microsoft Application to Get the Necessary Credentials for the Package

The following page https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app outlines the steps to register an application in your Microsoft tenant and obtain the necessary credentials for this package to work.

Official page

https://jeannot-muller.com/m365-entra-authentication-with-go

Documentation

Index

Constants

View Source
const AuthorizationURLPrefix = "https://login.microsoftonline.com/"

AuthorizationURLPrefix is a constant that represents the prefix of the authorization URL. It is used to construct the full authorization URL by appending the necessary components. The constant value is "https://login.microsoftonline.com/".

View Source
const AuthorizationURLSuffix = "/oauth2/v2.0/authorize"
View Source
const TokenURLSuffix = "/oauth2/v2.0/token"

Variables

Store is a package-level variable of type `*redistore.RediStore`. It represents the Redis store for session management. The `Store` variable is used to store and retrieve session data in the Redis database. It is initialized by the `InitializeStore` function and can be used in various functions throughout the package to handle session-related operations, such as session initialization, retrieval, and deletion.

Functions

func CSRFProtection

func CSRFProtection(c Config) func(http.Handler) http.Handler

CSRFProtection generates middleware to protect against CSRF attacks. The middleware adds CSRF tokens to all HTML forms in the application and verifies the tokens on form submission.

Parameters:

  • c: the configuration object with security key for CSRF protection

Returns:

  • A function that can be used as middleware in an HTTP handler chain.

func CallbackHandler

func CallbackHandler(w http.ResponseWriter, r *http.Request, c Config) error

CallbackHandler handles the callback from the authentication provider. It retrieves the authorization code from the URL, gets the access and refresh tokens, retrieves the user information, sets the session values, saves the session, and finally redirects the user to the landing page.

func InitializeStore

func InitializeStore(c Config) error

InitializeStore initializes the Redis store for session management based on the provided Config. It creates a new RediStore with the given parameters and assigns it to the package-level Store variable. It registers the Users and Tokens types to allow them to be stored in the session. It sets the options for the store, including the session path, maximum age, http-only flag, secure flag, and same-site mode based on the Config. If an error occurs during initialization, it prints an error message and exits the program. Finally, it prints a message indicating that the Redis Store is running at the specified address. Note: This function assumes that the Redis server is running on "localhost:6379". Note: This function assumes that the Redis server is running on "localhost:6379".

func LoginHandler

func LoginHandler(w http.ResponseWriter, r *http.Request, c Config) error

LoginHandler handles the login process. It checks if the user is already authenticated and redirects them to the original URL or landing page if they are. Otherwise, it constructs the login URL and redirects the user to it.

func LogoutHandler

func LogoutHandler(w http.ResponseWriter, r *http.Request, c Config) error

LogoutHandler clears the auth_token cookie, invalidates the user session, deletes the session from Redis, and redirects the user to the home page for logout.

func MiddlewareFactory

func MiddlewareFactory(c Config) func(http.Handler) http.Handler

MiddlewareFactory creates a middleware function that serves as the authorization middleware for protected routes. It checks if the session contains an access token and redirects to the login page if it doesn't. If an additional "auth_success" cookie is found, it allows the request to proceed without requiring an access token. It returns the middleware function that can be used in an HTTP handler chain.

Parameters:

  • c: the configuration object containing session information

Returns:

  • A middleware function that takes a http.Handler and returns a http.Handler.

func SetupCORS

func SetupCORS(config Config) func(http.Handler) http.Handler

SetupCORS sets up Cross-Origin Resource Sharing (CORS) middleware for HTTP handlers.

Parameters:

  • config: the configuration object containing CORS settings

Returns:

  • A function that can be used as middleware in an HTTP handler chain.

Types

type AuthorizationCode

type AuthorizationCode struct {
	Value string
}

AuthorizationCode represents an authorization code used for authentication and authorization.

type Config

type Config struct {
	ClientID         string
	ClientSecret     string
	TenantID         string
	HostNameDev      string
	HostNameProd     string
	LoginPath        string
	LandingPath      string
	ErrorPath        string
	RedirectPort     int
	RedirectPath     string
	Scope            string
	SessionName      string
	SessionMaxAge    int
	SecurityKeyCSRF  string
	SecurityKeyStore string
	IsProduction     bool
	RedisPort        int
	RedisHostName    string
	RedisPoolSize    int
	AllowOrigin      []string
	AllowMethods     []string
	AllowHeaders     []string
}

Config represents the configuration settings for the application.

It includes various fields such as client ID, client secret, tenant ID, host names, paths, redirect port, scope, session settings, security keys, production mode, and CORS settings.

This struct is used to initialize the application's configuration and provides access to the configuration values throughout the application.

func (Config) RedirectURL

func (c Config) RedirectURL() string

RedirectURL returns the URL that should be used for redirecting based on the configuration. The URL is constructed using the host name, scheme, and redirect path from the Config struct. If the IsProduction field is false, the development host name and redirect port are used, and the scheme is set to "http". Otherwise, the production host name and "https" scheme are used. The resulting URL returns a string.

type Tokens

type Tokens struct {
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
	ExpiresIn    int    `json:"expires_in"`
	TokenType    string `json:"token_type"`
}

Tokens represents the data structure for storing access and refresh tokens.

func GetTokens

func GetTokens(
	c Config,
	authCode AuthorizationCode,
	scope string,
) (t Tokens, err error)

GetTokens retrieves access and refresh tokens for the specified authorization code and scope, using the provided configuration.

It constructs the necessary form values, including the code, grant type, redirect URI, client ID, and scope. It makes a POST request to the authorization token URL with the form values. If the request is successful, it reads the response body and parses it into a Tokens struct. The Tokens struct contains the access token, refresh token, expires in, and token type.

If any error occurs during the process, it is wrapped and returned along with an empty Tokens struct. The error messages indicate the specific step in which the error occurred.

The function requires a Config struct, which holds the necessary configuration values such as client ID, client secret, tenant ID, redirect URL, and more. It also requires an AuthorizationCode and a scope string. The AuthorizationCode is obtained after successful authentication/authorization, and the scope represents the requested access permissions.

The function returns a Tokens struct and an error value. The Tokens struct contains the retrieved access and refresh tokens, while the error value indicates whether the token retrieval was successful or if any error occurred.

type Users

type Users struct {
	UserID            string   `json:"id"`
	BusinessPhones    []string `json:"businessPhones"`
	DisplayName       string   `json:"displayName"`
	FirstName         string   `json:"givenName"`
	JobTitle          string   `json:"jobTitle"`
	Email             string   `json:"mail"`
	MobilePhone       string   `json:"mobilePhone"`
	OfficeLocation    string   `json:"officeLocation"`
	PreferredLanguage string   `json:"preferredLanguage"`
	LastName          string   `json:"surname"`
	UserPrincipleName string   `json:"userPrincipalName"`
}

Users is a struct that represents user information. It contains various properties such as User ID, business phones, display name, first name, job title, email, mobile phone, office location, preferred language, last name, and user principal name. This struct is used to retrieve and store user information from the Microsoft Graph API.

func GetUserInfo

func GetUserInfo(accessToken string) (u Users, err error)

GetUserInfo retrieves the user's information from the Microsoft Graph API using the specified access token.

The access token is used to authenticate the request to the API. If the access token is valid and the request is successful, the user's information is returned as a Users struct. Otherwise, an error is returned indicating the failure to get the user's information.

The Users struct contains various properties representing the user's information such as ID, email, display name, job title, and more.

Jump to

Keyboard shortcuts

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