DEX是一款简单的用户认证系统,支持OpenID Connect (OIDC)
和OAuth 2.0
协议,并通过可插拔的连接器(Connectors)
支持对接多种认证后端。
介绍
简单的说,dex是一个认证代理
Dex
由 CoreOS 采用 Golang 开发
Dex
是一个使用 OpenID Connect
来驱动其他应用程序认证身份的服务
ID Tokens
由 OpenID Connect
和 Dex
的主要特性引入的OAuth2扩展
ID Tokens
由dex签名的 JWT,作为 OAuth2 响应的一部分返回,证明最终用户的身份
连接器(Connectors)
作为上游认证服务,支持多种实现,参考 https://dexidp.io/docs/connectors/github/
- 客户端实现参考
基于源码编译
$ git clone https://github.com/dexidp/dex.git
$ cd dex/
创建github app
server 端
$ make build
- 配置示例文件
examples/config-dev.yaml
,已集成 github 认证
# The base path of dex and the external name of the OpenID Connect service.
# This is the canonical URL that all clients MUST use to refer to dex. If a
# path is provided, dex's HTTP service will listen at a non-root URL.
issuer: http://127.0.0.1:5556/dex
# The storage configuration determines where dex stores its state. Supported
# options include SQL flavors and Kubernetes third party resources.
#
# See the documentation (https://dexidp.io/docs/storage/) for further information.
storage:
type: sqlite3
config:
file: examples/dex.db
# type: mysql
# config:
# host: localhost
# port: 3306
# database: dex
# user: mysql
# password: mysql
# ssl:
# mode: "false"
# type: postgres
# config:
# host: localhost
# port: 5432
# database: dex
# user: postgres
# password: postgres
# ssl:
# mode: disable
# type: etcd
# config:
# endpoints:
# - http://localhost:2379
# namespace: dex/
# type: kubernetes
# config:
# kubeConfigFile: $HOME/.kube/config
# Configuration for the HTTP endpoints.
web:
http: 0.0.0.0:5556
# Uncomment for HTTPS options.
# https: 127.0.0.1:5554
# tlsCert: /etc/dex/tls.crt
# tlsKey: /etc/dex/tls.key
# Configuration for dex appearance
# frontend:
# issuer: dex
# logoURL: theme/logo.png
# dir: web/
# theme: light
# Configuration for telemetry
telemetry:
http: 0.0.0.0:5558
# enableProfiling: true
# Uncomment this block to enable the gRPC API. This values MUST be different
# from the HTTP endpoints.
# grpc:
# addr: 127.0.0.1:5557
# tlsCert: examples/grpc-client/server.crt
# tlsKey: examples/grpc-client/server.key
# tlsClientCA: examples/grpc-client/ca.crt
# Uncomment this block to enable configuration for the expiration time durations.
# Is possible to specify units using only s, m and h suffixes.
# expiry:
# deviceRequests: "5m"
# signingKeys: "6h"
# idTokens: "24h"
# refreshTokens:
# reuseInterval: "3s"
# validIfNotUsedFor: "2160h" # 90 days
# absoluteLifetime: "3960h" # 165 days
# Options for controlling the logger.
# logger:
# level: "debug"
# format: "text" # can also be "json"
# Default values shown below
# oauth2:
# use ["code", "token", "id_token"] to enable implicit flow for web-only clients
# responseTypes: [ "code" ] # also allowed are "token" and "id_token"
# By default, Dex will ask for approval to share data with application
# (approval for sharing data from connected IdP to Dex is separate process on IdP)
# skipApprovalScreen: false
# If only one authentication method is enabled, the default behavior is to
# go directly to it. For connected IdPs, this redirects the browser away
# from application to upstream provider such as the Google login page
# alwaysShowLoginScreen: false
# Uncomment the passwordConnector to use a specific connector for password grants
# passwordConnector: local
# Instead of reading from an external storage, use this list of clients.
#
# If this option isn't chosen clients may be added through the gRPC API.
staticClients:
- id: example-app
redirectURIs:
- 'http://127.0.0.1:5555/callback'
name: 'Example App'
secret: ZXhhbXBsZS1hcHAtc2VjcmV0
# - id: example-device-client
# redirectURIs:
# - /device/callback
# name: 'Static Client for Device Flow'
# public: true
connectors:
- type: mockCallback
id: mock
name: Example
# - type: google
# id: google
# name: Google
# config:
# issuer: https://accounts.google.com
# # Connector config values starting with a "$" will read from the environment.
# clientID: $GOOGLE_CLIENT_ID
# clientSecret: $GOOGLE_CLIENT_SECRET
# redirectURI: http://127.0.0.1:5556/dex/callback
# hostedDomains:
# - $GOOGLE_HOSTED_DOMAIN
- type: github
id: github
name: github
config:
clientID: 078b153a10d37bd090b4
clientSecret: ed6ac8e983059d4c215659e64384283f1609f80a
redirectURI: http://127.0.0.1:5556/dex/callback
orgs:
- name: beehat
loadAllGroups: false
teamNameField: slug
useLoginAsID: false
# Let dex keep a list of passwords which can be used to login to dex.
enablePasswordDB: true
# A static list of passwords to login the end user. By identifying here, dex
# won't look in its underlying storage for passwords.
#
# If this option isn't chosen users may be added through the gRPC API.
staticPasswords:
- email: "admin@example.com"
# bcrypt hash of the string "password": $(echo password | htpasswd -BinC 10 admin | cut -d: -f2)
hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W"
username: "admin"
userID: "08a8684b-db88-4b73-90a9-3cd1661f5466"
说明:
- issuer 是外部会访问到的系统URL
- web 是服务端的地址
- telemetry 是监控指标抓取地址
- storage 是dexserver的存储设置
- dex 运行时跟踪包括 refresh_token、auth_code、keys、password 等的状态,因此需要将这些状态持久化
- 支持 SQLite3、Postgres、MySQL、memory 等
- 数据库添加用户
sqlite3 config/dex.db
sqlite> insert info password values('admin@example.com', '$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W', 'admin', '08a8684b-db88-4b73-90a9-3cd1661f5466');
sqlite> .quit
./bin/dex serve examples/config-dev.yaml
client 客户端
$ make bin/example-app
$ ./bin/example-app --listen http://0.0.0.0:5555 --issuer http://127.0.0.1:5556/dex --redirect-uri http://127.0.0.1:5555/callback
访问
- http://127.0.0.1:5555 点击 login 调整到登录页面
- 登录后获取的认证示例:
ID Token:
eyJhbGciOiJSUzI1NiIsImtpZCI6IjdiMzI5ODBiN2M3MTMzYmIwODBiZGE2MTZiMWVjOWExODM2NDgzODYifQ.eyJpc3MiOiJodHRwOi8vMTI3LjAuMC4xOjU1NTYvZGV4Iiwic3ViIjoiQ2dnMU1EUXhOVE0zTlJJR1oybDBhSFZpIiwiYXVkIjoiZXhhbXBsZS1hcHAiLCJleHAiOjE2NjkyMTAwMTEsImlhdCI6MTY2OTEyMzYxMSwiYXRfaGFzaCI6IkF4Vmt3dXNYd01GZ21pazdFMXZKRXciLCJjX2hhc2giOiJqMWhqTllWZXNRZmROYW9nbUg0emlBIiwiZW1haWwiOiI2QDE2Ni54eXoiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwibmFtZSI6ImVzdGFjayIsInByZWZlcnJlZF91c2VybmFtZSI6ImVzdGFjayJ9.nY3Gu9fmsWoJ7LwtyPTbBTxcm1rQAhs-hj9IdPJXZFwPahsNFpF3vIvD4U9vXihvCxi8vSlYxV8NNebL2PVhC76DxcAmUuLXpLijDdJ6jopYxc1MybyAwuZUdSezGodzvbUFUv_eWb97hPwS8bkzNoMD7AFxx79fnLTXvxx2BEgDt7-9eymPa7STsvjrAU9RzwIemPy8NOcnFQq3JmypFCe_QNJ5UE00JpfhHXB9YQcI4LxADuOCz00CbX8fc7kI7HcqTNaImLeUxCGyEAq5gGn4D1I5Ty93iREsI0oizJl9yt98sXKHJDjHaBCEN7F6gGtfoGTLzH7pfJbxLaXGSQ
Access Token:
eyJhbGciOiJSUzI1NiIsImtpZCI6IjdiMzI5ODBiN2M3MTMzYmIwODBiZGE2MTZiMWVjOWExODM2NDgzODYifQ.eyJpc3MiOiJodHRwOi8vMTI3LjAuMC4xOjU1NTYvZGV4Iiwic3ViIjoiQ2dnMU1EUXhOVE0zTlJJR1oybDBhSFZpIiwiYXVkIjoiZXhhbXBsZS1hcHAiLCJleHAiOjE2NjkyMTAwMTEsImlhdCI6MTY2OTEyMzYxMSwiYXRfaGFzaCI6Ijc0RlIyY2dCbGJVbmxpX1RnZkZUckEiLCJlbWFpbCI6IjZAMTY2Lnh5eiIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJuYW1lIjoiZXN0YWNrIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiZXN0YWNrIn0.fqJeYxLCXc2uRSMoUe-XL1Vnz0f4vqXbLmvZJynryo8eTGw2yB-T518Oct2d1eMooUlSUWTiKvhym0cgjAD15x_pZ-mRRaD6BQTJzQihDjLYlcBo6CE1V-vsr3RAP6wKbZRuSkMWeeuQW4C4YHgNlP94Rr-C6c16STXLW4OSd69KPn8Iv6rOlWqNpYL1EQsDfhTwhlUNOq0kHt4PjKEVjG0-eWnoXHU04OMoWkBGWmRl37hFbeMJB5MiGe63B874k1DUUTljiPoeLHeklLT7muxy6SBL22GnaEQ9ooZkMfOfBQLMBvnEXgkNK6N5HgxIyxljk90faXr-iwPPEg-ShQ
Claims:
{
"iss": "http://127.0.0.1:5556/dex",
"sub": "Cgg1MDQxNTM3NRIGZ2l0aHVi",
"aud": "example-app",
"exp": 1669210011,
"iat": 1669123611,
"at_hash": "AxVkwusXwMFgmik7E1vJEw",
"c_hash": "j1hjNYVesQfdNaogmH4ziA",
"email": "6@166.xyz",
"email_verified": true,
"name": "estack",
"preferred_username": "estack"
}
Refresh Token:
ChlvaTJpaHp2enBkZnl6dmY0bzNxN3NscjRhEhljM2U1Y2Q3bXV0Z3pzbG16b2I0b2hodWw3
扩展