使用说明
mcp身份验证
面向Go的OAuth 2.1授权服务器库,专为MCP(模型上下文协议)服务器设计。
提供一个完整的OAuth 2.1实现,包括PKCE、动态客户端注册(RFC 7591)、受保护的资源元数据(RFC 9728)和API密钥身份验证。将处理程序连接到HTTP多路复用器中,并带来自己的存储后端。
安装
go get github.com/alexjbarnes/mcp-auth
快速开始
package main
import (
"net/http"
mcpauth "github.com/alexjbarnes/mcp-auth"
)
func main() {
srv := mcpauth.New(mcpauth.Config{
ServerURL: "https://example.com",
Users: mcpauth.NewMapAuthenticator(map[string]string{
"alice": "password123",
}),
GrantTypes: []string{"authorization_code", "refresh_token", "client_credentials"},
})
defer srv.Stop()
mux := http.NewServeMux()
// Register all OAuth endpoints.
srv.Register(mux)
// Protect your application routes with the middleware.
mux.Handle("/mcp", srv.Middleware()(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
userID := mcpauth.RequestUserID(r.Context())
w.Write([]byte("hello " + userID))
})))
http.ListenAndServe(":8080", mux)
}
端点
srv.Register(mux) 导线:
| 方法 | 路径 | 描述 |
|---|---|---|
| 得到 | /.well-known/oauth-protected-resource |
受保护的资源元数据(RFC 9728) |
| 得到 | /.well-known/oauth-authorization-server |
授权服务器元数据(RFC 8414) |
| 职位 | /oauth/register |
动态客户端注册(RFC 7591) |
| 得到 | /oauth/authorize |
授权码流(显示登录页面) |
| 职位 | /oauth/authorize |
授权码流(处理登录) |
| 职位 | /oauth/token |
代币交换和刷新 |
API密钥
在没有OAuth流的情况下注册服务到服务身份验证的API密钥。
// With a prefix to distinguish from OAuth tokens.
srv := mcpauth.New(mcpauth.Config{
ServerURL: "https://example.com",
APIKeyPrefix: "sk_",
})
srv.RegisterAPIKey("sk_live_abc123", "service-account")
// Without a prefix. Tokens are speculatively checked as API keys
// and fall through to OAuth validation if not found.
srv := mcpauth.New(mcpauth.Config{
ServerURL: "https://example.com",
})
srv.RegisterAPIKey("abc123", "service-account")
// Register by pre-computed hash when you don't have the raw key.
srv.RegisterAPIKeyByHash(mcpauth.HashSecret("abc123"), "service-account")
预配置的客户端
注册绕过动态注册的服务器拥有的OAuth客户端。
err := srv.RegisterPreConfiguredClient(&mcpauth.OAuthClient{
ClientID: "my-service",
SecretHash: mcpauth.HashSecret("client-secret"),
GrantTypes: []string{"client_credentials"},
})
if err != nil {
// Grant type not supported by server configuration.
log.Fatal(err)
}
存储
默认情况下,所有内容都在内存中。为了实现持久存储,请实施 Persistence 接口并通过传递 Config.Persist.
type Persistence interface {
SaveOAuthToken(token OAuthToken) error
DeleteOAuthToken(tokenHash string) error
AllOAuthTokens() ([]OAuthToken, error)
SaveOAuthClient(client OAuthClient) error
DeleteOAuthClient(clientID string) error
AllOAuthClients() ([]OAuthClient, error)
SaveAPIKey(hash string, key APIKey) error
DeleteAPIKey(hash string) error
AllAPIKeys() (map[string]APIKey, error)
}
原始秘密(令牌、刷新令牌)永远不会传递给持久层。只存储哈希值。
用户认证
实施 UserAuthenticator 用于自定义凭证验证(LDAP、数据库等)。
type UserAuthenticator interface {
ValidateCredentials(ctx context.Context, username, password string) (userID string, err error)
}
MapAuthenticator 是一个由用户名/密码映射支持的内置实现。密码在构建时被散列,不会被保留。
users := mcpauth.NewMapAuthenticator(map[string]string{
"alice": "password123",
"bob": "hunter2",
})
可选实施 UserAccountChecker 在同一类型上启用中间件中的每个请求帐户验证(禁用用户而不撤销令牌)。
上下文助手
在中间件对请求进行身份验证后,从上下文中提取身份:
userID := mcpauth.RequestUserID(r.Context())
clientID := mcpauth.RequestClientID(r.Context())
ip := mcpauth.RequestRemoteIP(r.Context())
WithUserID 将用户ID注入上下文进行测试:
ctx := mcpauth.WithUserID(context.Background(), "test-user")
许可证
Apache 2.0