func (s *grpcServer) authToken(jwt jose.JWT) (string, *oidc.ClientMetadata, error) { ciRepo := s.server.ClientIdentityRepo keys, err := s.server.KeyManager.PublicKeys() if err != nil { log.Errorf("grpc.go: Failed to get keys: %v", err) return "", nil, errors.New("errorAccessDenied") } if len(keys) == 0 { log.Error("grpc.go: No keys available for verification client") return "", nil, errors.New("errorAccessDenied") } ok, err := oidc.VerifySignature(jwt, keys) if err != nil { log.Errorf("grpc.go: Failed to verify signature: %v", err) return "", nil, err } if !ok { log.Info("grpc.go: token signature is not verified") return "", nil, errors.New("invalid token") } clientID, err := oidc.VerifyClientClaims(jwt, s.server.IssuerURL.String()) if err != nil { log.Errorf("grpc.go: Failed to verify JWT claims: %v", err) return "", nil, errors.New("failed to verify jwt claims token") } md, err := ciRepo.Metadata(clientID) if md == nil || err != nil { log.Errorf("grpc.go: Failed to find clientID: %s, error=%v", clientID, err) return "", nil, err } //client must be admin in order to use login and register grpc apis. ok, err = ciRepo.IsDexAdmin(clientID) if err != nil { return "", nil, err } if !ok { log.Infof("grpc.go: Client [%s] is not admin", clientID) return "", nil, errors.New("errorAccessDenied") } log.Debugf("grpc.go: Authenticated token for client ID %s", clientID) return clientID, md, nil }
func (c *clientTokenMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) { respondError := func() { writeAPIError(w, http.StatusUnauthorized, newAPIError(errorAccessDenied, "missing or invalid token")) } if c.keysFunc == nil { log.Errorf("Misconfigured clientTokenMiddleware, keysFunc is not set") respondError() return } if c.ciRepo == nil { log.Errorf("Misconfigured clientTokenMiddleware, ClientIdentityRepo is not set") respondError() return } rawToken, err := oidc.ExtractBearerToken(r) if err != nil { log.Errorf("Failed to extract token from request: %v", err) respondError() return } jwt, err := jose.ParseJWT(rawToken) if err != nil { log.Errorf("Failed to parse JWT from token: %v", err) respondError() return } keys, err := c.keysFunc() if err != nil { log.Errorf("Failed to get keys: %v", err) writeAPIError(w, http.StatusUnauthorized, newAPIError(errorAccessDenied, "")) respondError() return } else if len(keys) == 0 { log.Error("No keys available for verification in client token middleware") writeAPIError(w, http.StatusUnauthorized, newAPIError(errorAccessDenied, "")) respondError() return } ok, err := oidc.VerifySignature(jwt, keys) if err != nil { log.Errorf("Failed to verify signature: %v", err) respondError() return } else if !ok { log.Info("Invalid token") respondError() return } clientID, err := oidc.VerifyClientClaims(jwt, c.issuerURL) if err != nil { log.Errorf("Failed to verify JWT claims: %v", err) respondError() return } md, err := c.ciRepo.Metadata(clientID) if md == nil || err != nil { log.Errorf("Failed to find clientID: %s, error=%v", clientID, err) respondError() return } log.Infof("Authenticated token for client ID %s", clientID) c.next.ServeHTTP(w, r) }