README
¶
oauth2w
oauth2w is a HTTP middleware that enables authorization via the OpenID Connect protocol.
Installation
go get github.com/i-core/oauth2w
How it works
- A client sends HTTP request that contains an OpenID Connect Access Token within the header
Authorization
. - The middleware requests user claims using the userinfo's endpoint of OpenID Connect Provider.
- The middleware requests user roles using the interface
oauth2w.RoleFinder
. - The middleware validates that the user has the required roles, and according to it, allows or not the HTTP request.
Note 1. Getting user roles is out of scope the library. You must provide an implementation of oauth2w.RoleFinder
that receives user claims and returns the user's roles.
Note 2. The middleware add the default role "_default" to each authenticated user. You can use it in order to transparently add an access to endpoints that each authenticated user must have an access for.
Usage
Simple
package main
import (
"fmt"
"net/http"
"os"
"github.com/i-core/oauth2w"
)
const oidcEndpoint = "https://openid-connect-provider.org"
func main() {
authw, err := oauth2w.New(oidcEndpoint, &RoleFinder{})
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
http.HandleFunc("/profile", authw([]string{"user"})(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("Profile page")
}))
http.HandleFunc("/admin", authw([]string{"admin"})(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("Admin page")
}))
fmt.Println(http.ListenAndServe(":8080", nil))
}
// RoleFinder finds user roles in the user's claims.
type RoleFinder struct {}
func (f *RoleFinder) FindRoles(claims map[string]interface{}) ([]string, error) {
roleClaim, ok := claims['roles']
if !ok {
return nil, nil
}
roles, ok := roleClaim.([]interface{})
!ok {
return nil, fmt.Errorf("invalid role claim \"roles\"")
}
var vv []string
for _, role := range roles {
s, ok := role.(string)
if !ok {
return nil, fmt.Errorf("invalid role claim \"roles\"")
}
vv = append(vv, s)
}
return vv, nil
}
Logging
package main
import (
"fmt"
"github.com/i-core/oauth2w"
)
const oidcEndpoint = "https://openid-connect-provider.org"
func main() {
logPrintFn := func(ctx context.Context) func(string, ...interface{}) {
return func(msg string, keysAndValues ...interface{}) {
params = append([]interface{}{"Info:", msg}, ...keysAndValues)
fmt.Println(params...)
}
}
logDebugFn := func(ctx context.Context) func(string, ...interface{}) {
return func(msg string, keysAndValues ...interface{}) {
params = append([]interface{}{"Debug:", msg}, ...keysAndValues)
fmt.Println(params...)
}
}
authw, err := oauth2w.New(oidcEndpoint, &RoleFinder{}, oauth2w.WithLogPrint(logPrintFn), oauth2w.WithLogDebug(logDebugFn))
// ...
}
Accessing user data
package main
import (
"fmt"
"net/http"
"os"
"github.com/i-core/oauth2w"
)
const oidcEndpoint = "https://openid-connect-provider.org"
func main() {
authw, err := oauth2w.New(oidcEndpoint, &RoleFinder{})
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
http.HandleFunc("/profile", authw(func(w http.ResponseWriter, r *http.Request) {
user := oauth2w.FindUser(r.Context())
fmt.Printf("User %v\n", user)
}))
fmt.Println(http.ListenAndServe(":8080", nil))
}
Usage with Ory Hydra and Werther
When you use OpenID Connect Provider ORY Hydra with Identity Provider Werther you can use
an implementation of RoleFinder
from package github.com/i-core/oauth2w/werther
.
With the default role claim:
package main
import (
"github.com/i-core/oauth2w"
"github.com/i-core/oauth2w/werther"
)
const (
oidcEndpoint = "https://openid-connect-provider.org"
roleGroupID = "myapp"
)
func main() {
authw, err := oauth2w.New(oidcEndpoint, werther.NewRoleFinder(roleGroupID))
// ...
}
With a custom name of the role claim:
package main
import (
"github.com/i-core/oauth2w"
"github.com/i-core/oauth2w/werther"
)
const (
oidcEndpoint = "https://openid-connect-provider.org"
roleClaim = "http://my-company.org/claims/roles"
roleGroupID = "myapp"
)
func main() {
authw, err := oauth2w.New(oidcEndpoint, werther.NewRoleFinder(roleGroupID).WithRoleClaim(roleClaim))
// ...
}
Contributing
Thanks for your interest in contributing to this project. Get started with our Contributing Guide.
License
The code in this project is licensed under MIT license.
Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func New ¶
func New(endpoint string, roleFinder RoleFinder, opts ...Option) (func([]string) func(http.Handler) http.Handler, error)
New returns a new instance of the middleware.
To authorize HTTP request the middleware validates that the user has all required roles. When there is no required roles the middleware authorizes all HTTP requests.
To get user roles the middleware requests user claims from an OpenID Connect Provider, and then transforms the claims to roles using the interface RoleFinder.
endpoint is an endpoint of an OpenID Connect Provider.
Types ¶
type Option ¶
type Option func(*config)
Option describes a function for the middleware's configuration.
func WithLogDebug ¶
WithLogDebug returns an option that configures a debug logger.
func WithLogPrint ¶
WithLogPrint returns an option that configures an info logger.
type RoleFinder ¶
RoleFinder is an interface to find user roles using the user's claims.