mirror of
https://github.com/wso2/open-mcp-auth-proxy.git
synced 2025-06-28 01:23:30 +00:00
71 lines
1.8 KiB
Go
71 lines
1.8 KiB
Go
package authz
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/golang-jwt/jwt/v4"
|
|
"github.com/wso2/open-mcp-auth-proxy/internal/config"
|
|
"github.com/wso2/open-mcp-auth-proxy/internal/util"
|
|
)
|
|
|
|
type ScopeValidator struct{}
|
|
|
|
// Evaluate and checks the token claims against one or more required scopes.
|
|
func (d *ScopeValidator) ValidateAccess(
|
|
r *http.Request,
|
|
claims *jwt.MapClaims,
|
|
config *config.Config,
|
|
) AccessControlResult {
|
|
env, err := util.ParseRPCRequest(r)
|
|
if err != nil {
|
|
return AccessControlResult{DecisionDeny, "bad JSON-RPC request"}
|
|
}
|
|
requiredScopes := util.GetRequiredScopes(config, env.Method)
|
|
if len(requiredScopes) == 0 {
|
|
return AccessControlResult{DecisionAllow, ""}
|
|
}
|
|
|
|
required := make(map[string]struct{}, len(requiredScopes))
|
|
for _, s := range requiredScopes {
|
|
s = strings.TrimSpace(s)
|
|
if s != "" {
|
|
required[s] = struct{}{}
|
|
}
|
|
}
|
|
|
|
var tokenScopes []string
|
|
if claims, ok := (*claims)["scope"]; ok {
|
|
switch v := claims.(type) {
|
|
case string:
|
|
tokenScopes = strings.Fields(v)
|
|
case []interface{}:
|
|
for _, x := range v {
|
|
if s, ok := x.(string); ok && s != "" {
|
|
tokenScopes = append(tokenScopes, s)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
tokenScopeSet := make(map[string]struct{}, len(tokenScopes))
|
|
for _, s := range tokenScopes {
|
|
tokenScopeSet[s] = struct{}{}
|
|
}
|
|
|
|
var missing []string
|
|
for s := range required {
|
|
if _, ok := tokenScopeSet[s]; !ok {
|
|
missing = append(missing, s)
|
|
}
|
|
}
|
|
|
|
if len(missing) == 0 {
|
|
return AccessControlResult{DecisionAllow, ""}
|
|
}
|
|
return AccessControlResult{
|
|
DecisionDeny,
|
|
fmt.Sprintf("missing required scope(s): %s", strings.Join(missing, ", ")),
|
|
}
|
|
}
|