<p>I have been trying to implement istio authorization using Oauth2 and keycloak. I have followed few articles related to this <a href="https://medium.com/@senthilrch/api-authentication-using-istio-ingress-gateway-oauth2-proxy-and-keycloak-part-2-of-2-dbb3fb9cd0d0" rel="nofollow noreferrer">API Authentication: Configure Istio IngressGateway, OAuth2-Proxy and Keycloak</a>, <a href="https://istio.io/latest/docs/reference/config/security/authorization-policy/" rel="nofollow noreferrer">Authorization Policy</a></p>
<p><strong>Expected output:</strong> My idea is to implement keycloak authentication where oauth2 used as an external Auth provider in the istio ingress gateway.
when a user try to access my app in <code>&lt;ingress host&gt;/app</code> , it should automatically redirect to keycloak login page.</p>
<p>How do i properly redirect the page to keycloak login screen for authentication ?</p>
<p><strong>problem:</strong>
When i try to access <code>&lt;ingress host&gt;/app</code>, the page will take 10 seconds to load and it gives status 403 access denied.
if i remove the authorization policy (<em>kubectl delete -f authorization-policy.yaml</em>) within that 10 seconds, it will redirect to the login screen (<em>keycloak</em>)</p>
<p>oauth2.yaml</p>
<pre><code>apiVersion: v1
kind: Service
metadata:
  labels:
    app: oauth-proxy
  name: oauth-proxy
spec:
  type: NodePort
  selector:
    app: oauth-proxy
  ports:
  - name: http-oauthproxy
    port: 4180
    nodePort: 31023
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: oauth-proxy
  name: oauth-proxy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: &quot;oauth-proxy&quot;
  template:
    metadata:
      labels:
        app: oauth-proxy
    spec:
      containers:
      - name: oauth-proxy
        image: &quot;quay.io/oauth2-proxy/oauth2-proxy:v7.2.0&quot;
        ports:
        - containerPort: 4180
        args:
          - --http-address=0.0.0.0:4180
          - --upstream=http://test-web-app:3000
          - --set-xauthrequest=true
          - --pass-host-header=true
          - --pass-access-token=true
        env:
          # OIDC Config
          - name: &quot;OAUTH2_PROXY_PROVIDER&quot;
            value: &quot;keycloak-oidc&quot;
          - name: &quot;OAUTH2_PROXY_OIDC_ISSUER_URL&quot;
            value: &quot;http://192.168.1.2:31020/realms/my_login_realm&quot;
          - name: &quot;OAUTH2_PROXY_CLIENT_ID&quot;
            value: &quot;my_nodejs_client&quot;
          - name: &quot;OAUTH2_PROXY_CLIENT_SECRET&quot;
            value: &quot;JGEQtkrdIc6kRSkrs89BydnfsEv3VoWO&quot;
          # Cookie Config
          - name: &quot;OAUTH2_PROXY_COOKIE_SECURE&quot;
            value: &quot;false&quot;
          - name: &quot;OAUTH2_PROXY_COOKIE_SECRET&quot;
            value: &quot;ZzBkN000Wm0pQkVkKUhzMk5YPntQRUw_ME1oMTZZTy0=&quot;
          - name: &quot;OAUTH2_PROXY_COOKIE_DOMAINS&quot;
            value: &quot;*&quot;
          # Proxy config
          - name: &quot;OAUTH2_PROXY_EMAIL_DOMAINS&quot;
            value: &quot;*&quot;
          - name: &quot;OAUTH2_PROXY_WHITELIST_DOMAINS&quot;
            value: &quot;*&quot;
          - name: &quot;OAUTH2_PROXY_HTTP_ADDRESS&quot;
            value: &quot;0.0.0.0:4180&quot;
          - name: &quot;OAUTH2_PROXY_SET_XAUTHREQUEST&quot;
            value: &quot;true&quot;
          - name: OAUTH2_PROXY_PASS_AUTHORIZATION_HEADER
            value: &quot;true&quot;
          - name: OAUTH2_PROXY_SSL_UPSTREAM_INSECURE_SKIP_VERIFY
            value: &quot;true&quot;
          - name: OAUTH2_PROXY_SKIP_PROVIDER_BUTTON
            value: &quot;true&quot;
          - name: OAUTH2_PROXY_SET_AUTHORIZATION_HEADER
            value: &quot;true&quot;
</code></pre>
<p>keycloak.yaml</p>
<pre><code>apiVersion: v1
kind: Service
metadata:
  name: keycloak
spec:
  type: NodePort
  selector:
    app: keycloak
  ports:
  - name: http-keycloak
    port: 8080
    nodePort: 31020
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keycloak
spec:
  selector:
    matchLabels:
      app: keycloak
  template:
    metadata:
      labels:
        app: keycloak
    spec:
      containers:
      - name: keycloak
        image: quay.io/keycloak/keycloak:17.0.0
        ports:
        - containerPort: 8080
        args: [&quot;start-dev&quot;]
        env:
        - name: KEYCLOAK_ADMIN
          value: &quot;admin&quot;
        - name: KEYCLOAK_ADMIN_PASSWORD
          value: &quot;admin&quot;
</code></pre>
<p>istio-operator.yaml</p>
<pre><code>apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    accessLogFile: /dev/stdout
    extensionProviders:
    - name: &quot;oauth2-proxy&quot;
      envoyExtAuthzHttp:
        service: &quot;oauth-proxy.default.svc.cluster.local&quot;
        port: &quot;4180&quot; # The default port used by oauth2-proxy.
        includeHeadersInCheck: [&quot;authorization&quot;, &quot;cookie&quot;,&quot;x-forwarded-access-token&quot;,&quot;x-forwarded-user&quot;,&quot;x-forwarded-email&quot;,&quot;x-forwarded-proto&quot;,&quot;proxy-authorization&quot;,&quot;user-agent&quot;,&quot;x-forwarded-host&quot;,&quot;from&quot;,&quot;x-forwarded-for&quot;,&quot;accept&quot;,&quot;x-auth-request-redirect&quot;] # headers sent to the oauth2-proxy in the check request.
        headersToUpstreamOnAllow: [&quot;authorization&quot;, &quot;path&quot;, &quot;x-auth-request-user&quot;, &quot;x-auth-request-email&quot;, &quot;x-auth-request-access-token&quot;,&quot;x-forwarded-access-token&quot;] # headers sent to backend application when request is allowed.
        headersToDownstreamOnDeny: [&quot;content-type&quot;, &quot;set-cookie&quot;] # headers sent back to the client when request is denied.
        
</code></pre>
<p>gateway.yaml</p>
<pre><code>apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: test-gateway
  namespace : istio-system
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - '*'
</code></pre>
<p>virtual-service.yaml</p>
<pre><code>apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: gateway-vs
spec:
  hosts:
    - '*'
  gateways: 
    - istio-system/test-gateway
  http:
    - match:
      - uri:
          prefix: /oauth2
      route:
      - destination:
          host: oauth-proxy.default.svc.cluster.local
          port:
            number: 4180
    - match:
      - uri:
          prefix: /app
      route:
      - destination:
          host: test-web-app.default.svc.cluster.local
          port:
            number: 3000
</code></pre>
<p>authorization-policy.yaml</p>
<pre><code>apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: example-auth-policy
spec:
  action: CUSTOM
  provider:
    name: &quot;oauth2-proxy&quot;
  rules:
  - to:
    - operation:
        paths: [&quot;/app&quot;]
        notPaths: [&quot;/oauth2/*&quot;]
</code></pre>

<p>The redirection issue solved by updating authorization policy</p>
<pre><code>apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: example-auth-policy
  namespace: istio-system
spec:
  action: CUSTOM
  provider:
    name: &quot;oauth2-proxy&quot;
  rules:
  - to:
    - operation:       
        paths: [&quot;/app&quot;]
        notPaths: [&quot;/oauth2/*&quot;]
  selector:
    matchLabels:
      app: istio-ingressgateway
</code></pre>
<ul>
<li>Added <code>istio-system</code> namespace instead of workload namespace (it was default in my case)</li>
<li>Forgot to add <code>matchLabels</code>.</li>
</ul>
