Skip to content

Commit

Permalink
OIDC v1 implementation & doc reference (#828)
Browse files Browse the repository at this point in the history
  • Loading branch information
jthann authored Oct 18, 2022
1 parent 301ceb6 commit 7a75cc8
Show file tree
Hide file tree
Showing 12 changed files with 676 additions and 13 deletions.
75 changes: 75 additions & 0 deletions doc/reference/filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@
- [DataBuilder](#databuilder)
- [Configuration](#configuration-18)
- [Results](#results-18)
- [OIDCAdaptor](#OIDCAdaptor)
- [Configuration](#configuration-19)
- [Results](#results-19)
- [Common Types](#common-types)
- [pathadaptor.Spec](#pathadaptorspec)
- [pathadaptor.RegexpReplace](#pathadaptorregexpreplace)
Expand Down Expand Up @@ -983,6 +986,78 @@ the context.
|-----------------|---------------------------------------------------|
| buildErr | Error happens when building the data |

## OIDCAdaptor

OpenID Connect(OIDC) is an identity layer on top of the OAuth 2.0 protocol. It enables Clients to verify
the identity of the End-User based on the authentication performed by an Authorization Server, as well as
to obtain basic profile information about the End-User.

For identity platforms that implement standard OIDC specification like [Google Accounts](https://accounts.google.com)、[OKTA](https://www.okta.com/)、
[Auth0](https://auth0.com/)、[Authing](https://www.authing.cn/). configure `discovery` endpoint as below example:

```yaml
name: demo-pipeline
kind: Pipeline
flow:
- filter: oidc
jumpIf: { oidcFiltered: END }
filters:
- name: oidc
kind: OIDCAdaptor
cookieName: oidc-auth-cookie
clientId: <Your ClientId>
clientSecret: <Your clientSecret>
discovery: https://accounts.google.com/.well-known/openid-configuration #Replace your own discovery
redirectURI: /oidc/callback
```

For third platforms that only implement OAuth2.0 like GitHub, users should configure `authorizationEndpoint`、
`tokenEndpoint`、`userinfoEndpoint` at the same time as below example:

```yaml
name: demo-pipeline
kind: Pipeline
flow:
- filter: oidc
jumpIf: { oidcFiltered: END }
filters:
- name: oidc
kind: OIDCAdaptor
cookieName: oidc-auth-cookie
clientId: <Your ClientId>
clientSecret: <Your clientSecret>
authorizationEndpoint: https://github.com/login/oauth/authorize
tokenEndpoint: https://github.com/login/oauth/access_token
userinfoEndpoint: https://api.github.com/user
redirectURI: /oidc/callback
```

### Configuration

| Name | Type | Description | Required |
|-----------------------|--------|---------------------------------------------------------------------------------------------------------------------------|----------|
| clientId | string | The OAuth2.0 app client id | Yes |
| clientSecret | string | The OAuth2.0 app client secret | Yes |
| cookieName | string | Used to check if necessary to launch OpenIDConnect flow | No |
| discovery | string | Standard OpenID Connect discovery endpoint URL of the identity server | No |
| authorizationEndpoint | string | OAuth2.0 authorization endpoint URL | No |
| tokenEndpoint | string | OAuth2.0 token endpoint URL | No |
| userInfoEndpoint | string | OAuth2.0 user info endpoint URL | No |
| redirectURI | string | The callback uri registered in identity server, for example: <br/>`https://example.com/oidc/callback` or `/oidc/callback` | Yes |

### Results
| Value | Description |
|-----------------|----------------------------------------|
| oidcFiltered | The request is handled by OIDCAdaptor. |


After OIDCAdaptor handled, following OIDC related information can be obtained from Easegress HTTP request headers:

* **X-User-Info**: Base64 encoded OIDC End-User basic profile.
* **X-Origin-Request-URL**: End-User origin request URL before OpenID Connect or OAuth2.0 flow.
* **X-Id-Token**: The ID Token returned by OpenID Connect flow.
* **X-Access-Token**: The AccessToken returned by OpenId Connect or OAuth2.0 flow.


## Common Types

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.18

require (
github.com/ArthurHlt/go-eureka-client v1.1.0
github.com/MicahParks/keyfunc v1.0.3
github.com/Shopify/sarama v1.36.0
github.com/bytecodealliance/wasmtime-go v1.0.0
github.com/eclipse/paho.mqtt.golang v1.4.1
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962 h1:KeNholpO2xKjgaaSyd+DyQRrsQjhbSeS7qe4nEw8aQw=
github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962/go.mod h1:kC29dT1vFpj7py2OvG1khBdQpo3kInWP+6QipLbdngo=
github.com/MicahParks/keyfunc v1.0.3 h1:rKakzF/Gd2QjFPCqSG9SshrWs0oRZffc/c4pVjCXDr0=
github.com/MicahParks/keyfunc v1.0.3/go.mod h1:R8RZa27qn+5cHTfYLJ9/+7aSb5JIdz7cl0XFo0o4muo=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
Expand Down Expand Up @@ -354,6 +356,7 @@ github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptG
github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c=
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog=
github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
Expand Down
2 changes: 2 additions & 0 deletions pkg/cluster/cluster_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ type (
PutAndDelete(map[string]*string) error
PutAndDeleteUnderLease(map[string]*string) error

PutUnderTimeout(key, value string, timeout time.Duration) error

Delete(key string) error
DeletePrefix(prefix string) error

Expand Down
8 changes: 8 additions & 0 deletions pkg/cluster/clustertest/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type MockedCluster struct {
MockedGetRawPrefix func(prefix string) (map[string]*mvccpb.KeyValue, error)
MockedGetWithOp func(key string, ops ...cluster.ClientOp) (map[string]string, error)
MockedPut func(key, value string) error
MockedPutUnderTimeout func(key, value string, timeout time.Duration) error
MockedPutUnderLease func(key, value string) error
MockedPutAndDelete func(map[string]*string) error
MockedPutAndDeleteUnderLease func(map[string]*string) error
Expand Down Expand Up @@ -123,6 +124,13 @@ func (mc *MockedCluster) Put(key, value string) error {
return nil
}

func (mc *MockedCluster) PutUnderTimeout(key, value string, timeout time.Duration) error {
if mc.MockedPutUnderTimeout != nil {
return mc.MockedPutUnderTimeout(key, value, timeout)
}
return nil
}

// PutUnderLease implements interface function PutUnderLease
func (mc *MockedCluster) PutUnderLease(key, value string) error {
if mc.MockedPutUnderLease != nil {
Expand Down
16 changes: 16 additions & 0 deletions pkg/cluster/op.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"go.etcd.io/etcd/api/v3/mvccpb"
clientv3 "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/client/v3/concurrency"
"time"
)

// PutUnderLease stores data under lease.
Expand Down Expand Up @@ -223,3 +224,18 @@ func (c *cluster) STM(apply func(concurrency.STM) error) error {
_, err = concurrency.NewSTM(client, apply)
return err
}

func (c *cluster) PutUnderTimeout(key, value string, timeout time.Duration) error {
client, err := c.getClient()
if err != nil {
return err
}
ctx, cancel := c.requestContext()
defer cancel()
lgr, err := client.Lease.Grant(ctx, int64(timeout.Seconds()))
if err != nil {
return err
}
_, err = client.Put(ctx, key, value, clientv3.WithLease(lgr.ID))
return err
}
Loading

0 comments on commit 7a75cc8

Please sign in to comment.