diff --git a/controllers/oauth2.go b/controllers/oauth2.go index 04fc5b3..99100a0 100644 --- a/controllers/oauth2.go +++ b/controllers/oauth2.go @@ -162,10 +162,12 @@ func (o *OAuthController) InternalAuthForward() { Name: "csrf_token", Value: o.XSRFToken(), }) // may be a problem... we should check if token is valid on our side - // prefers a refresh token call fmt.Println("InternalAuthForward", isToken, err) + // prefers a refresh token call if err != nil || !isToken { o.Ctx.ResponseWriter.WriteHeader(401) + } else { + o.Ctx.ResponseWriter.WriteHeader(200) } o.ServeJSON() } diff --git a/docker-compose.yml b/docker-compose.yml index 58aa585..294b9ce 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -28,6 +28,7 @@ services: - "traefik.enable=true" - "traefik.http.routers.whoami.entrypoints=web" - "traefik.http.routers.whoami.rule=Host(`localhost`)" + - "traefik.routers.whoami.rule=Path(/whoami)" - "traefik.http.routers.whoami.tls=false" - "traefik.http.services.whoami.loadbalancer.server.port=80" - "traefik.http.routers.whoami.middlewares=auth" diff --git a/infrastructure/auth_connector/hydra_connector.go b/infrastructure/auth_connector/hydra_connector.go index e1baa73..e22f1f0 100644 --- a/infrastructure/auth_connector/hydra_connector.go +++ b/infrastructure/auth_connector/hydra_connector.go @@ -182,6 +182,7 @@ func (a HydraConnector) Login(username string, cookies ...*http.Cookie) (t *Toke c := claims.GetClaims().AddClaimsToToken(username, pp.Data[0].(*peer.Peer).Url) b, _ = json.Marshal(c) token.AccessToken = strings.ReplaceAll(token.AccessToken, "ory_at_", "") + "." + base64.StdEncoding.EncodeToString(b) + token.Active = true return token, nil } diff --git a/infrastructure/claims/hydra_claims.go b/infrastructure/claims/hydra_claims.go index 2879957..bda3af9 100644 --- a/infrastructure/claims/hydra_claims.go +++ b/infrastructure/claims/hydra_claims.go @@ -4,6 +4,7 @@ import ( "crypto/sha256" "encoding/pem" "errors" + "fmt" "oc-auth/conf" "oc-auth/infrastructure/perms_connectors" "oc-auth/infrastructure/utils" @@ -21,7 +22,7 @@ func (h HydraClaims) generateKey(relation string, path string) (string, error) { return "", err } p := strings.ReplaceAll(strings.ToUpper(path), "/", "_") - return strings.ToLower(method.String()) + "_" + p, nil + return strings.ToLower(method.String()) + "_" + strings.ReplaceAll(p, ":", ""), nil } // decode key expect to extract method and path from key @@ -63,6 +64,17 @@ func (h HydraClaims) encodeSignature(host string) (string, error) { return SignDefault(hashed[:], spkiBlock.Bytes) } +func (h HydraClaims) clearBlank(path []string) []string { + // clear blank + newPath := []string{} + for _, p := range path { + if p != "" { + newPath = append(newPath, p) + } + } + return newPath +} + func (h HydraClaims) DecodeClaimsInToken(host string, method string, forward string, sessionClaims Claims, publicKey string, external bool) (bool, error) { idTokenClaims := sessionClaims.Session.IDToken if idTokenClaims["signature"] == nil { @@ -74,27 +86,33 @@ func (h HydraClaims) DecodeClaimsInToken(host string, method string, forward str } claims := sessionClaims.Session.AccessToken path := strings.ReplaceAll(forward, "http://"+host, "") - splittedPath := strings.Split(path, "/") + splittedPath := h.clearBlank(strings.Split(path, "/")) for m, p := range claims { - splittedP := strings.Split(p.(string), "/") + match := true + splittedP := h.clearBlank(strings.Split(p.(string), "/")) if len(splittedP) != len(splittedPath) { continue } for i, v := range splittedP { + fmt.Println(v, splittedPath[i]) if strings.Contains(v, ":") { // is a param continue } else if v != splittedPath[i] { - meth, _, err := h.decodeKey(m, external) - if err != nil { - continue - } - perm := perms_connectors.Permission{ - Relation: "permits" + strings.ToLower(meth.String()), - Object: p.(string), - } - return perms_connectors.GetPermissionConnector().CheckPermission(perm, nil, true), nil + match = false + break } } + if match { + meth, _, err := h.decodeKey(m, external) + if err != nil { + continue + } + perm := perms_connectors.Permission{ + Relation: "permits" + strings.ToUpper(meth.String()), + Object: p.(string), + } + return perms_connectors.GetPermissionConnector().CheckPermission(perm, nil, true), nil + } } return false, errors.New("no permission found") } @@ -109,11 +127,11 @@ func (h HydraClaims) AddClaimsToToken(userId string, host string) Claims { claims.Session.AccessToken = make(map[string]interface{}) claims.Session.IDToken = make(map[string]interface{}) for _, perm := range perms { - key, err := h.generateKey(strings.ReplaceAll(perm.Relation, "permits", ""), perm.Object) + key, err := h.generateKey(strings.ReplaceAll(perm.Relation, "permits", ""), perm.Subject) if err != nil { continue } - claims.Session.AccessToken[key] = perm.Object + claims.Session.AccessToken[key] = perm.Subject } sign, err := h.encodeSignature(host) if err != nil { diff --git a/infrastructure/perms_connectors/keto_connector.go b/infrastructure/perms_connectors/keto_connector.go index 747ab3d..d7fece3 100644 --- a/infrastructure/perms_connectors/keto_connector.go +++ b/infrastructure/perms_connectors/keto_connector.go @@ -69,21 +69,13 @@ func (k KetoConnector) CheckPermission(perm Permission, permDependancies *Permis log.Error().Msg("Permission denied : Ask illegal permission") return false } - caller := tools.NewHTTPCaller(map[tools.DataType]map[tools.METHOD]string{}) - var responseBody map[string]interface{} - host := conf.GetConfig().PermissionConnectorHost - port := fmt.Sprintf("%v", conf.GetConfig().PermissionConnectorPort) - resp, err := caller.CallGet("http://"+host+":"+port, "/relation-tuples/check"+k.permToQuery(perm, permDependancies)) + perms, err := k.GetPermission(perm.Object, perm.Relation) if err != nil { log := oclib.GetLogger() log.Error().Msg(err.Error()) return false } - err = json.Unmarshal(resp, &responseBody) - if err != nil || responseBody["allowed"] == nil { - return false - } - return responseBody["allowed"].(bool) + return len(perms) > 0 } func (k KetoConnector) DeleteRole(roleID string) (string, int, error) {