Skip to content
This repository has been archived by the owner on Jul 28, 2021. It is now read-only.

Invalid discoveryUrl Causes Confusing Too Many Redirects Error #43

Open
devstein opened this issue Feb 8, 2020 · 8 comments
Open

Invalid discoveryUrl Causes Confusing Too Many Redirects Error #43

devstein opened this issue Feb 8, 2020 · 8 comments

Comments

@devstein
Copy link
Contributor

devstein commented Feb 8, 2020

We are evaluating the app-identity-and-access-adapter and I am trying to deploy it to Minkube to test it out; however, I am getting an infinite redirect loop at the implicit /oidc/callback endpoint (ERR_TOO_MANY_REDIRECTS). I imagine the adapter is not intercepting the request correctly. Any idea what could be going wrong? Is this a configuration issue or an issue specific to Minikube? See my manifests below.

I am using the latest Minikube and Istio versions.

---
apiVersion: "security.cloud.ibm.com/v1"
kind: OidcConfig
metadata:
  name: oidc-provider-config
spec:
  discoveryUrl: *******
  clientId: ********
  clientSecret: **********
---
apiVersion: "security.cloud.ibm.com/v1"
kind: Policy
metadata:
  name: samplepolicy
spec:
  targets:
    -
      serviceName: httpbin
      paths:
        - exact: /headers
          method: ALL
          policies:
            - policyType: oidc
              config: oidc-provider-config
              redirectUri: "https://github.com/ibm-cloud-security/app-identity-and-access-adapter"
# httpbin for testing
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: httpbin
---
apiVersion: v1
kind: Service
metadata:
  name: httpbin
  labels:
    app: httpbin
spec:
  ports:
  - name: http
    port: 8000
    targetPort: 80
  selector:
    app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
      version: v1
  template:
    metadata:
      labels:
        app: httpbin
        version: v1
    spec:
      serviceAccountName: httpbin
      containers:
      - image: docker.io/kennethreitz/httpbin
        imagePullPolicy: IfNotPresent
        name: httpbin
        ports:
        - containerPort: 80
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: httpbin-gateway
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
  - "*"
  gateways:
  - httpbin-gateway
  http:
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        port:
          number: 8000
        host: httpbin
@k3a
Copy link

k3a commented Feb 8, 2020

Change exact: /headers to prefix: /headers (or don't specify exact/prefix uri rule).
I think the problem you are experiencing is that /headers/oidc/callback upon returning from the OpenID provider is not handled by this adabter unless the policy matches it too. I am not sure.

You should probably also remove redirectUri from the Policy.

@devstein
Copy link
Contributor Author

devstein commented Feb 9, 2020

@k3a I changes exact: /headers to prefix: /headers and removed the redirectUri but the behavior didn't change. I also tried to simplify it with a catch-all prefix: /. Here is the latest Policy config:

kind: Policy
metadata:
  name: samplepolicy
spec:
  targets:
    -
      serviceName: httpbin
      paths:
        - prefix: /
          method: ALL
          policies:
            - policyType: oidc
              config: oidc-provider-config

@k3a
Copy link

k3a commented Feb 9, 2020

That's odd. I basically use the following basic config which works for me. It even uses bookinfo-gateway. You can try to delete the browser cookie or use Private window / Firefox container to start from scratch.

Also check the logs kubectl logs -l app=appidentityandaccessadapter -n istio-system .

And you can also use "Persist logs" in the browser developer tools and watch the redirection flow to see why it redirects and to which URLs.

It is also possible to increase logging verbosity. See the logging section of Helm values.yaml.

apiVersion: "security.cloud.ibm.com/v1"
kind:       OidcConfig
metadata:
  name:      oidc-provider-config
  namespace: default
spec:
  authMethod:   client_secret_basic
  discoveryUrl: https://DOMAIN/.well-known/openid-configuration
  clientId:     CLIENT_ID
  clientSecret: CLIENT_SECRET
---
apiVersion: "security.cloud.ibm.com/v1"
kind:       Policy
metadata:
  name:      httpbin
  namespace: default
spec:
  targets:
    - serviceName: httpbin
      paths:
        - method: ALL
          policies:
            - policyType: oidc
              config: oidc-provider-config
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin
spec:
  selector:
    matchLabels:
      app: httpbin
  template:
    metadata:
      labels:
        app: httpbin
    spec:
      containers:
      - name: httpbin
        image: kennethreitz/httpbin:latest
        resources:
          limits:
            memory: "228Mi"
            cpu: "500m"
        ports:
        - containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
  name:  httpbin
spec:
  selector:
    app:  httpbin
  ports:
  - name:  http
    port:  80
    targetPort:  80
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
  - "*"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    - uri:
        prefix: /httpbin
    rewrite:
      uri: /
    route:
    - destination:
        host: httpbin
        port:
          number: 80
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: httpbin
spec:
  host: httpbin
  trafficPolicy:
    tls:
      mode: DISABLE

@devstein
Copy link
Contributor Author

devstein commented Feb 9, 2020

@k3a I ran into the same issue with your configuration, so I enabled debug level logging and found the root cause. The appidentityandaccessadapter was failing because I was using Okta's oauth-authorization-server url instead of the openid-configuration url (See logs below)

Fixing the discoveryUrl, fixed the redirect issue; however, now I am seeing the following error after successfully logging in:

UNAUTHENTICATED:handler-appidentityandaccessadapter.handler.istio-system:invalid_token: token validation error - expected claim `aud` to match one of: [CLIENT_ID]

where CLIENT_ID is my app's OIDC client id.

  1. Should I make an issue for better handling of an invalid discovery config error?
  2. How is the aud claim currently set? Is there any way to configure it?

// When I create the OidcConfig
{
  "level": "debug",
  "ts": "2020-02-09t21:08:20.148z",
  "caller": "authserver/authserver.go:77",
  "msg": "initialization from discovery endpoint failed. will retry later.",
  "source": "appidentityandaccessadapter-adapter",
  "url": "OKTA_URL"
}
{
  "level": "debug",
  "ts": "2020-02-09t21:08:20.230z",
  "caller": "authserver/authserver.go:206",
  "msg": "could not sync discovery endpoint",
  "source": "appidentityandaccessadapter-adapter",
  "url": "OKTA_URL",
  "error": "invalid discovery config: missing `userinfo_endpoint`"
}
// When I make a request
{
  "level": "debug",
  "ts": "2020-02-09T21:10:14.736Z",
  "caller": "engine/engine.go:68",
  "msg": "Checking policies",
  "source": "appidentityandaccessadapter-adapter",
  "count": 1
}
{
  "level": "info",
  "ts": "2020-02-09T21:10:14.736Z",
  "caller": "adapter/adapter.go:71",
  "msg": "Executing OIDC policies",
  "source": "appidentityandaccessadapter-adapter"
}
{
  "level": "debug",
  "ts": "2020-02-09T21:10:14.736Z",
  "caller": "web/web.go:149",
  "msg": "Tokens not found in cache.",
  "source": "appidentityandaccessadapter-adapter",
  "client_name": "default/oidc-provider-config"
}
{
  "level": "debug",
  "ts": "2020-02-09T21:10:14.736Z",
  "caller": "web/web.go:123",
  "msg": "Handling new user authentication",
  "source": "appidentityandaccessadapter-adapter"
}
{
  "level": "debug",
  "ts": "2020-02-09T21:10:14.736Z",
  "caller": "web/web.go:335",
  "msg": "Initiating redirect to identity provider using redirect URL: http://192.168.64.3:30418/httpbin/headers/oidc/callback",
  "source": "appidentityandaccessadapter-adapter"
}
{
  "level": "debug",
  "ts": "2020-02-09T21:10:14.805Z",
  "caller": "authserver/authserver.go:206",
  "msg": "Could not sync discovery endpoint",
  "source": "appidentityandaccessadapter-adapter",
  "url": "OKTA_URL",
  "error": "invalid discovery config: missing `userinfo_endpoint`"
}
{
  "level": "debug",
  "ts": "2020-02-09T21:10:14.805Z",
  "caller": "authserver/authserver.go:187",
  "msg": "Could not sync discovery endpoint",
  "source": "appidentityandaccessadapter-adapter",
  "url": "OKTA_URL",
  "error": "invalid discovery config: missing `userinfo_endpoint`"
}

@devstein devstein changed the title Minikube -- Too Many Redirects Invalid discoveryUrl Causes Confusing Too Many Redirects Error Feb 9, 2020
@devstein
Copy link
Contributor Author

devstein commented Feb 10, 2020

@k3a Narrowed down Okta access token validation error.

The default JWT validation rules for OIDC checks for the client id in the aud claim, but Okta only returns the client id for the aud claim in the ID token and the access token returns the specified audiences for the authorization server. A workaround is specifying the client id as the only audience in for a custom authorization server in Okta

// createDefaultRules generates the default JWT validation rules for the given client
func createDefaultRules(action Action) []v1.Rule {
	switch action.Type {
	case policy.OIDC:
		return []v1.Rule{
			{
				Claim: aud,
				Match: "ANY",
				Values: []string{action.Client.ID()},
			},
		}
	default:
		return []v1.Rule{}
	}
}

@k3a
Copy link

k3a commented Feb 14, 2020

It is a default rule if no rule is specified. Try to append your own rule(s):

apiVersion: "security.cloud.ibm.com/v1"
kind:       Policy
metadata:
  name:      httpbin
  namespace: default
spec:
  targets:
    - serviceName: httpbin
      paths:
        - method: ALL
          policies:
            - policyType: oidc
              config: oidc-provider-config
              rules: 
               - claim: aud
                  match: ANY
                  source: id_token
                  values:
                    - YOUR_AUD_CLAIM

Although I found out this adapter is pre-release. There are couple of things which needs fixing to make it work well-enough. Overall, it's written quite well so not much is remaining. I will try to fix some issues by sending more pull requests soon...

@devstein
Copy link
Contributor Author

@k3a Thanks! I'm happy to contribute as well if you need help!

@mzeitlin
Copy link

@k3a The aud issue still exists even after I set policy rules. I have tried multiple different types of configuration of the rules, but it still continues to use the default rules.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants