oauth

package module
v0.0.0-...-02fca97 Latest Latest
Warning

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

Go to latest
Published: Jan 8, 2021 License: MIT Imports: 11 Imported by: 0

README

oauth middleware

OAuth 2.0 Authorization Server & Authorization Middleware for Gin-Gonic

This library offers an OAuth 2.0 Authorization Server based on Gin-Gonic and an Authorization Middleware usable in Resource Servers developed with Gin-Gonic.

Build status

Build Status

Authorization Server

The Authorization Server is implemented by the struct OAuthBearerServer that manages two grant types of authorizations (password and client_credentials). This Authorization Server is made to provide an authorization token usable for consuming resources API.

Password grant type

OAuthBearerServer supports the password grant type, allowing the token generation for username / password credentials.

Client Credentials grant type

OAuthBearerServer supports the client_credentials grant type, allowing the token generation for client_id / client_secret credentials.

Authorization Code and Implicit grant type

These grant types are currently partially supported implementing AuthorizationCodeVerifier interface. The method ValidateCode is called during the phase two of the authorization_code grant type evalutations.

Refresh token grant type

If authorization token will expire, the client can regenerate the token calling the authorization server and using the refresh_token grant type.

Authorization Middleware

The Gin-Gonic middleware BearerAuthentication intercepts the resource server calls and authorizes only resource requests containing a valid bearer token.

Token Formatter

Authorization Server crypts the token using the Token Formatter and Authorization Middleware decrypts the token using the same Token Formatter. This library contains a default implementation of the formatter interface called SHA256RC4TokenSecureFormatter based on the algorithms SHA256 and RC4. Programmers can develop their Token Formatter implementing the interface TokenSecureFormatter and this is really recommended before publishing the API in a production environment.

Credentials Verifier

The interface CredentialsVerifier defines the hooks called during the token generation process. The methods are called in this order:

  • ValidateUser() or ValidateClient() called first for credentials verification
  • AddClaims() used for add information to the token that will be encrypted
  • StoreTokenId() called after the token generation but before the response, programmers can use this method for storing the generated Ids
  • AddProperties() used for add clear information to the response

There is another method in the CredentialsVerifier interface that is involved during the refresh token process. In this case the methods are called in this order:

  • ValidateTokenId() called first for TokenId verification, the method receives the TokenId related to the token associated to the refresh token
  • AddClaims() used for add information to the token that will be encrypted
  • StoreTokenId() called after the token regeneration but before the response, programmers can use this method for storing the generated Ids
  • AddProperties() used for add clear information to the response

Authorization Server usage example

This snippet shows how to create an authorization server

func main() {
	router := gin.New()
	router.Use(gin.Recovery())
	router.Use(gin.Logger())

    s := oauth.NewOAuthBearerServer(
		"mySecretKey-10101",
		time.Second*120,
		&TestUserVerifier{},
		nil)
	router.POST("/token", s.UserCredentials)
	router.POST("/auth", s.ClientCredentials)
	
	router.Run(":9090")
}

See /test/authserver/main.go for the full example.

Authorization Middleware usage example

This snippet shows how to use the middleware

    authorized := router.Group("/")
	// use the Bearer Athentication middleware
	authorized.Use(oauth.Authorize("mySecretKey-10101", nil))

	authorized.GET("/customers", GetCustomers)
	authorized.GET("/customers/:id/orders", GetOrders)

See /test/resourceserver/main.go for the full example.

Note that the authorization server and the authorization middleware are both using the same token formatter and the same secret key for encryption/decryption.

Note

This master branch introduces breaking changes in the interface CredentialsVerifier methods ValidateUser, ValidateClient and AddClaims. Refer to v1 branch for the previous implementation. Updated server implementation in v3 due to go.uuid library change.

Reference

License

MIT

Documentation

Index

Constants

View Source
const (
	TOKEN_TYPE = "Bearer"
)

Variables

This section is empty.

Functions

func Authorize

func Authorize(secretKey string, formatter TokenSecureFormatter) ghttp.HandlerFunc

Authorize is the OAuth 2.0 middleware for Gin-Gonic resource server. Authorize creates a BearerAuthentication middlever and return the Authorize method.

func CheckBasicAuthentication

func CheckBasicAuthentication(username, password string, r *ghttp.Request) error

Check Basic Autrhorization header credentials

func GetBasicAuthentication

func GetBasicAuthentication(r *ghttp.Request) (username, password string, err error)

GetBasicAuthentication get username and password from Authorization header

Types

type Any

type Any interface{}

type AuthorizationCodeVerifier

type AuthorizationCodeVerifier interface {
	// ValidateCode checks the authorization code and returns the user credential
	ValidateCode(clientID, clientSecret, code, redirectURI string, req *http.Request) (string, error)
}

AuthorizationCodeVerifier defines the interface of the Authorization Code verifier

type AuthorizeInfo

type AuthorizeInfo struct {
	//授权类型,此值固定为“code”。
	ResponseType string `p:"response_type" v:"required"`
	//申请QQ登录成功后,分配给应用的appid。
	ClientId string `p:"client_id" v:"required"`
	//成功授权后的回调地址,必须是注册appid时填写的主域名下的地址,建议设置为网站首页或网站的用户中心。注意需要将url进行URLEncode。
	RedirectUri string `p:"redirect_uri" v:"required"`
	//client端的状态值。用于第三方应用防止CSRF攻击,成功授权后回调时会原样带回。请务必严格按照流程检查用户与state参数状态的绑定。
	State string `p:"state" v:"required"`
	//请求用户授权时向用户显示的可进行授权的列表。
	//可填写的值是API文档中列出的接口,以及一些动作型的授权(目前仅有:do_like),如果要填写多个接口名称,请用逗号隔开。
	//例如:scope=get_user_info,list_album,upload_pic,do_like
	//不传则默认请求对接口get_user_info进行授权。
	//建议控制授权项的数量,只传入必要的接口名称,因为授权项越多,用户越可能拒绝进行任何授权。
	Scope string `p:"scope"`
	//仅PC网站接入时使用。
	//用于展示的样式。不传则默认展示为PC下的样式。
	//如果传入“mobile”,则展示为mobile端下的样式。
	Display string `p:"display"`
}

type BearerAuthentication

type BearerAuthentication struct {
	// contains filtered or unexported fields
}

BearerAuthentication middleware for Gin-Gonic

func NewBearerAuthentication

func NewBearerAuthentication(secretKey string, formatter TokenSecureFormatter) *BearerAuthentication

NewBearerAuthentication create a BearerAuthentication middleware

func (*BearerAuthentication) Authorize

func (ba *BearerAuthentication) Authorize(r *ghttp.Request)

Authorize verifies the bearer token authorizing or not the request. Token is retreived from the Authorization HTTP header that respects the format Authorization: Bearer {access_token}

type CancelAuthorizeInfo

type CancelAuthorizeInfo struct {
	//成功授权后的回调地址,必须是注册appid时填写的主域名下的地址,建议设置为网站首页或网站的用户中心。注意需要将url进行URLEncode。
	RedirectUri string `form:"redirect_uri" json:"redirect_uri" binding:"required"`
	//client端的状态值。用于第三方应用防止CSRF攻击,成功授权后回调时会原样带回。请务必严格按照流程检查用户与state参数状态的绑定。
	State string `form:"state" json:"state" binding:"required"`
}

type CredentialsVerifier

type CredentialsVerifier interface {
	// Validate username and password returning an error if the user credentials are wrong
	ValidateUser(username, password, scope string, req *http.Request) error
	// Validate clientId and secret returning an error if the client credentials are wrong
	ValidateClient(clientID, clientSecret, scope string, req *http.Request) error
	// Provide additional claims to the token
	AddClaims(credential, tokenID, tokenType, scope string) (map[string]string, error)
	// Optionally store the tokenID generated for the user
	StoreTokenId(credential, tokenID, refreshTokenID, tokenType string) error
	// Provide additional information to the authorization server response
	AddProperties(credential, tokenID, tokenType string, scope string) (map[string]string, error)
	// Optionally validate previously stored tokenID during refresh request
	ValidateTokenId(credential, tokenID, refreshTokenID, tokenType string) error
}

CredentialsVerifier defines the interface of the user and client credentials verifier.

type OAuthBearerServer

type OAuthBearerServer struct {
	TokenTTL time.Duration
	// contains filtered or unexported fields
}

OAuthBearerServer is the OAuth 2 Bearer Server implementation.

func NewOAuthBearerServer

func NewOAuthBearerServer(secretKey string,
	ttl time.Duration,
	verifier CredentialsVerifier,
	formatter TokenSecureFormatter) *OAuthBearerServer

NewOAuthBearerServer creates new OAuth 2 Bearer Server

func (*OAuthBearerServer) AuthorizationCode

func (s *OAuthBearerServer) AuthorizationCode(r *ghttp.Request)

AuthorizationCode manages authorization code grant type requests for the phase two of the authorization process

func (*OAuthBearerServer) ClientCredentials

func (s *OAuthBearerServer) ClientCredentials(r *ghttp.Request)

ClientCredentials manages client credentials grant type requests

func (*OAuthBearerServer) UserCredentials

func (s *OAuthBearerServer) UserCredentials(r *ghttp.Request)

UserCredentials manages password grant type requests

type RC4TokenSecureFormatter

type RC4TokenSecureFormatter struct {
	// contains filtered or unexported fields
}

func NewRC4TokenSecurityProvider

func NewRC4TokenSecurityProvider(key []byte) *RC4TokenSecureFormatter

func (*RC4TokenSecureFormatter) CryptToken

func (sc *RC4TokenSecureFormatter) CryptToken(source []byte) ([]byte, error)

func (*RC4TokenSecureFormatter) DecryptToken

func (sc *RC4TokenSecureFormatter) DecryptToken(source []byte) ([]byte, error)

type RefreshToken

type RefreshToken struct {
	CreationDate   time.Time `json:"date"`
	TokenId        string    `json:"id_token"`
	RefreshTokenId string    `json:"id_refresh_token"`
	Credential     string    `json:"credential"`
	TokenType      string    `json:"type"` // "U" for user, "C" for client
	Scope          string    `json:"scope"`
}

RefreshToken structure included in the authorization server response

type SHA256RC4TokenSecureFormatter

type SHA256RC4TokenSecureFormatter struct {
	// contains filtered or unexported fields
}

func NewSHA256RC4TokenSecurityProvider

func NewSHA256RC4TokenSecurityProvider(key []byte) *SHA256RC4TokenSecureFormatter

func (*SHA256RC4TokenSecureFormatter) CryptToken

func (sc *SHA256RC4TokenSecureFormatter) CryptToken(source []byte) ([]byte, error)

func (*SHA256RC4TokenSecureFormatter) DecryptToken

func (sc *SHA256RC4TokenSecureFormatter) DecryptToken(source []byte) ([]byte, error)

type TestUserVerifier

type TestUserVerifier struct {
}

func (*TestUserVerifier) AddClaims

func (*TestUserVerifier) AddClaims(credential, tokenID, tokenType, scope string) (map[string]string, error)

AddClaims provides additional claims to the token

func (*TestUserVerifier) AddProperties

func (*TestUserVerifier) AddProperties(credential, tokenId, tokenType string, scope string) (map[string]string, error)

AddProperties provides additional information to the token response

func (*TestUserVerifier) StoreTokenId

func (*TestUserVerifier) StoreTokenId(credential, tokenId, refreshTokenID, tokenType string) error

StoreTokenId saves the token Id generated for the user

func (*TestUserVerifier) ValidateClient

func (*TestUserVerifier) ValidateClient(clientID, clientSecret, scope string, req *http.Request) error

ValidateClient validates clientId and secret returning an error if the client credentials are wrong

func (*TestUserVerifier) ValidateCode

func (*TestUserVerifier) ValidateCode(clientID, clientSecret, code, redirectURI string, req *http.Request) (string, error)

ValidateCode validates token Id

func (*TestUserVerifier) ValidateTokenId

func (*TestUserVerifier) ValidateTokenId(credential, tokenId, refreshTokenID, tokenType string) error

ValidateTokenId validates token Id

func (*TestUserVerifier) ValidateUser

func (*TestUserVerifier) ValidateUser(username, password, scope string, req *http.Request) error

ValidateUser validates username and password returning an error if the user credentials are wrong

type Token

type Token struct {
	Id           string            `json:"id_token"`
	CreationDate time.Time         `json:"date"`
	ExperesIn    time.Duration     `json:"expires_in"` // secs
	Credential   string            `json:"credential"`
	Scope        string            `json:"scope"`
	Claims       map[string]string `json:"claims"`
	TokenType    string            `json:"type"` // "U" for user, "C" for client
}

Token structure generated by the authorization server

type TokenProvider

type TokenProvider struct {
	// contains filtered or unexported fields
}

func NewTokenProvider

func NewTokenProvider(formatter TokenSecureFormatter) *TokenProvider

func (*TokenProvider) CryptRefreshToken

func (tp *TokenProvider) CryptRefreshToken(t *RefreshToken) (token string, err error)

func (*TokenProvider) CryptToken

func (tp *TokenProvider) CryptToken(t *Token) (token string, err error)

func (*TokenProvider) DecryptRefreshTokens

func (tp *TokenProvider) DecryptRefreshTokens(refreshToken string) (refresh *RefreshToken, err error)

func (*TokenProvider) DecryptToken

func (tp *TokenProvider) DecryptToken(token string) (t *Token, err error)

type TokenResponse

type TokenResponse struct {
	Token        string            `json:"access_token"`
	RefreshToken string            `json:"refresh_token"`
	TokenType    string            `json:"token_type"` // bearer
	ExperesIn    int64             `json:"expires_in"` // secs
	Properties   map[string]string `json:"properties"`
}

TokenResponse is the authorization server response

type TokenSecureFormatter

type TokenSecureFormatter interface {
	CryptToken(source []byte) ([]byte, error)
	DecryptToken(source []byte) ([]byte, error)
}

Directories

Path Synopsis
test

Jump to

Keyboard shortcuts

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