目录
1、docker搭建hydra,环境配置:
2、搭建完成后服务调用:
2.1保证服务正常启动:
2.2 通过postman调用,获取client_id:
2.3 通过client_id,实现oauth2/auth调用
3. 通过go语言实现oidc验证:
1、docker搭建hydra,环境配置:
环境:windows10
docker-compose.yml:
version: "3.7"
services:
hydra:
image: oryd/hydra:v2.0.2
ports:
- "4444:4444" # 公共端口
- "4445:4445" # 管理端口
- "5555:5555" # 用于 Hydra 令牌用户的端口
command: serve -c /etc/config/hydra/hydra.yml all --dev
volumes:
- type: bind
source: C:\workspace\hydra\config
target: /etc/config/hydra
environment:
- DSN=postgres://hydra:secret@postgresd:5432/hydra?sslmode=disable&max_conns=20&max_idle_conns=4
restart: unless-stopped
depends_on:
- hydra-migrate
networks:
- intranet
hydra-migrate:
image: oryd/hydra:v2.0.2
environment:
- DSN=postgres://hydra:secret@postgresd:5432/hydra?sslmode=disable&max_conns=20&max_idle_conns=4
command: migrate -c /etc/config/hydra/hydra.yml sql -e --yes #这个是在容器中
volumes:
- type: bind
source: C:\workspace\hydra\config # 公共端口挂的卷是windows上
target: /etc/config/hydra
restart: on-failure
networks:
- intranet
consent:
environment:
- HYDRA_ADMIN_URL=http://hydra:4445
image: oryd/hydra-login-consent-node:v2.0.2
ports:
- "3000:3000"
restart: unless-stopped
networks:
- intranet
postgresd:
image: postgres:11.8
ports:
- "5432:5432"
environment:
- POSTGRES_USER=hydra
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=hydra
networks:
- intranet
networks:
intranet:
配置yaml:
serve:
cookies:
same_site_mode: Lax
urls:
self:
issuer: http://127.0.0.1:4444
consent: http://127.0.0.1:3000/consent
login: http://127.0.0.1:3000/login
logout: http://127.0.0.1:3000/logout
secrets:
system:
- youReallyNeedToChangeThis
oidc:
subject_identifiers:
supported_types:
- pairwise
- public
pairwise:
salt: youReallyNeedToChangeThis
2、搭建完成后服务调用:
2.1保证服务正常启动:
2.2 通过postman调用,获取client_id:
post:http://localhost:4445/admin/clients
body:
{
"client_name": "crm",
"token_endpoint_auth_method": "client_secret_basic",
"redirect_uris": [
"http://127.0.0.1:5555/callback"
],
"scope": "openid offline",
"grant_types": [
"authorization_code",
"refresh_token",
"implicit",
"client_credentials"
],
"response_types": [
"code",
"id_token",
"token"
]
}
2.3 通过client_id,实现oauth2/auth调用
3. 通过go语言实现oidc验证:
只是写了个思路,流程没有走通,只供参考,有厉害的大神可以完善补充一下,下面的代码只是提供了思路,搭建完上面的环境后,可以用以自己玩耍,有兴趣的流程自己走通完善:
package main
import (
"context"
"fmt"
"log"
"net/http"
"os"
"github.com/coreos/go-oidc"
"golang.org/x/oauth2"
)
func main() {
ctx := context.Background()
// 创建 OIDC 配置
provider, err := oidc.NewProvider(ctx, "http://127.0.0.1:4444")
if err != nil {
log.Fatalf("Failed to create OIDC provider: %v", err)
}
// 创建 OAuth2 配置
oauth2Config := oauth2.Config{
ClientID: "af7da551-1ddd-4e6e-9b52-62d7535e57f2", // 你的 OAuth2 客户端 ID
ClientSecret: os.Getenv("CLIENT_SECRET"), // 你的 OAuth2 客户端密钥
RedirectURL: "http://127.0.0.1:5555/callback", // 你的回调 URL
Endpoint: provider.Endpoint(),
Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
}
// 创建 OIDC 验证器
verifier := provider.Verifier(&oidc.Config{ClientID: oauth2Config.ClientID})
log.Printf("Received verifier: %s", verifier)
// 设置回调处理函数
http.HandleFunc("/oauth2/auth", func(w http.ResponseWriter, r *http.Request) {
// 获取 OAuth2 令牌
log.Printf("Received url: %s", r.URL.Query())
code := r.URL.Query().Get("code")
log.Printf("Received code: %s", code)
if code == "" {
http.Error(w, "Missing code parameter", http.StatusBadRequest)
return
}
log.Printf("Received code: %s", code)
oauth2Token, err := oauth2Config.Exchange(ctx, code)
if err != nil {
http.Error(w, fmt.Sprintf("Failed to exchange token: %v", err), http.StatusInternalServerError)
return
}
// 使用令牌获取用户信息
idToken, ok := oauth2Token.Extra("id_token").(string)
if !ok {
http.Error(w, "No id_token", http.StatusInternalServerError)
return
}
// 验证 ID 令牌
_, err = verifier.Verify(ctx, idToken)
if err != nil {
http.Error(w, fmt.Sprintf("Failed to verify token: %v", err), http.StatusUnauthorized)
return
}
// 验证通过,输出用户信息
fmt.Fprintf(w, "Authentication successful! User: %v", oauth2Token)
})
// 启动服务器
log.Fatal(http.ListenAndServe(":8080", nil))
}