From ab35252eed1383d16c950031810be9bbdd22b058 Mon Sep 17 00:00:00 2001 From: Jianfei Hu Date: Fri, 13 Aug 2021 01:06:07 +0000 Subject: [PATCH 1/6] Update authservice using external authz. Signed-off-by: Jianfei Hu --- Makefile | 3 +- bookinfo-example/README.md | 77 +++++++++++-------- ...hservice-configmap-template-for-authn.yaml | 14 ++-- bookinfo-example/config/bookinfo-gateway.yaml | 4 +- .../bookinfo-with-authservice-template.yaml | 3 +- ...ge-external-authz-envoyfilter-sidecar.yaml | 2 +- ...e-self-signed-certs-for-ingress-gateway.sh | 10 +-- src/filters/filter_chain.cc | 8 +- 8 files changed, 70 insertions(+), 51 deletions(-) diff --git a/Makefile b/Makefile index d59b0215..abfb744f 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ SRCS=$(shell find . -name '*.cc') HDRS=$(shell find . -name '*.h') TARGET:=//src/main:auth_server BAZEL_FLAGS:= --verbose_failures +IMAGE?=authservice:$(USER) all: build test docs @@ -18,7 +19,7 @@ compose: docker-compose up --build docker: build - rm -rf build_release && mkdir -p build_release && cp -r bazel-bin/ build_release && docker build -f build/Dockerfile.runner -t authservice:$(USER) . + rm -rf build_release && mkdir -p build_release && cp -r bazel-bin/ build_release && docker build . -f build/Dockerfile.runner -t $(IMAGE) && docker push $(IMAGE) docker-from-scratch: docker build -f build/Dockerfile.builder -t authservice:$(USER) . diff --git a/bookinfo-example/README.md b/bookinfo-example/README.md index ac6981de..7eece42d 100644 --- a/bookinfo-example/README.md +++ b/bookinfo-example/README.md @@ -14,7 +14,8 @@ Things needed before starting: provider will be needed to configure Authservice. ### Pre-requisites: -1. Download Istio 1.3 or greater. For example: + +1. Download Istio 1.9 or greater. For example: [`scripts/download-istio-1.4.sh`](scripts/download-istio-1.4.sh) @@ -27,12 +28,24 @@ provider will be needed to configure Authservice. [`scripts/generate-self-signed-certs-for-ingress-gateway.sh`](scripts/generate-self-signed-certs-for-ingress-gateway.sh) +1. Configure the Istio mesh config with an [external authorization provider](https://istio.io/latest/docs/tasks/security/authorization/authz-custom/) as `sample-ext-authz-grpc`. + + ```yaml + data: + mesh: |- + extensionProviders: + - name: "sample-ext-authz-grpc" + envoyExtAuthzGrpc: + service: ext.authz.local + port: "10003" + ``` ## Deploy Bookinfo Using the Authservice for Token Acquisition (Sidecar integration) The goal of these steps is the protect the `productpage` service with OIDC authentication provided by the mesh. These steps demonstrate how to: + 1. Configure the Authservice to provide token acquisition for end-users of the `productpage` service 1. Deploy the Authservice along with the Bookinfo sample app, in the same pod as the `productpage` service 1. Configure Istio authentication for the `productpage` service, using standard Istio features @@ -41,22 +54,19 @@ These steps demonstrate how to: To keep things simple, we deploy everything into the default namespace and we don't enable authentication for the other services of the Bookinfo app aside from `productpage`. +1. Prepare your OIDC provider configuration. For our example, we are using Google as IdP. +Follow [instructions](https://developers.google.com/identity/protocols/oauth2/openid-connect) to create one +if needed. + 1. Setup a `ConfigMap` for Authservice. Fill in [`config/authservice-configmap-template-for-authn.yaml`](config/authservice-configmap-template-for-authn.yaml) - to include the OIDC provider's configurations. Currently, only the `oidc` filter can be configured in the `ConfigMap`. See [here](../docs/README.md) - for the description of each field. Once the values have been substituted, apply the `ConfigMap`. + to include the OIDC provider's configurations. Currently, only the `oidc` filter can be configured in the + `ConfigMap`. See [here](../docs/README.md) for the description of each field. Once the values + have been substituted, apply the `ConfigMap`. `kubectl apply -f config/authservice-configmap-template-for-authn.yaml` ### -1. The Github Package Registry does not work seamlessly with k8s until [issue #870](https://github.com/kubernetes-sigs/kind/issues/870) - is fixed and released. As a workaround, manually `docker pull` the latest authservice image from - [https://github.com/istio-ecosystem/authservice/packages](https://github.com/istio-ecosystem/authservice/packages) - and push it to an accessible image registry (e.g. Docker Hub). - See the ["Using the authservice docker image" section in the README.md](https://github.com/istio-ecosystem/authservice/blob/master/README.md#using-the-authservice-docker-image) - for more information. -1. Edit [`config/bookinfo-with-authservice-template.yaml`](config/bookinfo-with-authservice-template.yaml) - and replace the authservice image name with the reference to the image in the registry from the step above. - Then apply the file to deploy Bookinfo and Authservice. +1. Apply the authservice deployment. `kubectl apply -f config/bookinfo-with-authservice-template.yaml` @@ -64,6 +74,12 @@ other services of the Bookinfo app aside from `productpage`. Note that the Authservice will be deployed in the same Pod as `productpage`. +1. Configure the product page to enable authservice via a `CUSTOM` action authorization policy. + + ```shell + kubectl apply -f ./config/ext-authz-productpage.yaml + ``` + 1. If the `callback` or `logout` paths in [`config/authservice-configmap-template-for-authn.yaml`](config/authservice-configmap-template-for-authn.yaml) were edited in a previous step, then edit those same paths in [`config/bookinfo-gateway.yaml`](config/bookinfo-gateway.yaml). Otherwise, no edit is needed. When ready, apply the file to create the ingress gateway and routing rules for Bookinfo: @@ -82,28 +98,18 @@ other services of the Bookinfo app aside from `productpage`. and without activating the Authservice, so the `productpage` UI should show in the browser without being asked to authenticate. -1. Edit the `issuer` and `jwksUri` settings in [`config/bookinfo-authn-policy-template.yaml`](config/bookinfo-authn-policy-template.yaml). - Apply the Authentication Policy for the Bookinfo application: +1. We're ready to put the Authservice into the data path for `productpage` by + using an [Istio ExternalAuthorization](https://istio.io/latest/docs/tasks/security/authorization/authz-custom/). - `kubectl apply -f config/bookinfo-authn-policy-template.yaml` - - Wait about a minute for the policy to take effect, then visit the Bookinfo `productpage` UI with a browser again. - The page should not be accessible by an unauthenticated user, giving a 401 `Origin authentication failed.` error message. - - The UI is now protected by Istio's authentication JWT checking feature, but nothing is helping the user authenticate, - acquire tokens, save those tokens, or transmit those tokens to the `productpage` service. Authservice to the rescue! + `kubectl apply -f config/productpage-external-authz-envoyfilter-sidecar.yaml` -1. We're ready to put the Authservice into the data path for `productpage` by adding - the [External Authorization filter](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/ext_authz_filter#config-http-filters-ext-authz) - using an [Istio EnvoyFilter](https://istio.io/docs/reference/config/networking/v1alpha3/envoy-filter/). - This example shows how to insert the External Authorization filter in the sidecar of the `productpage` app. - The filter is inserted before the [Istio Authentication Policy](https://istio.io/docs/tasks/security/authn-policy/), - which was added in the previous step. +1. Access the application at the `localhost:8443` via port forwarding, https://localhost:8443/productpage. - `kubectl apply -f config/productpage-external-authz-envoyfilter-sidecar.yaml` + ```shell + kubectl port-forward service/istio-ingressgateway 8443:443 -n istio-system + ``` - Wait about a minute for the policy to take effect, then visit the Bookinfo `productpage` UI with a browser again. - This time the browser should redirect to the OIDC provider's login page. Upon login, the authenticated user should + The browser should redirect to the OIDC provider's login page. Upon login, the authenticated user should be redirected back and gain access to the `productpage`. This works because the Authservice is involved in every request to the `productpage` service. @@ -295,3 +301,14 @@ The steps of using Authservice at the Ingress-gateway are roughly the same as th 1. The path part of the configured `callback_uri`, and if configured, the `logout.path`, must be paths that are routable to the app by the ingress gateway's `VirtualService`, or else the Authservice at the gateway will not receieve those requests and will not be able to process them. This is a perhaps counter-intuitive since the Authservice container is no longer running in the app's pod, so it may not feel like this is needed, but it is required. Better user experience and more sample configs will be added in the future. + +## FAQ + +Where I can find the authservice images? + +1. The Github Package Registry does not work seamlessly with k8s until [issue #870](https://github.com/kubernetes-sigs/kind/issues/870) + is fixed and released. As a workaround, manually `docker pull` the latest authservice image from + [https://github.com/istio-ecosystem/authservice/packages](https://github.com/istio-ecosystem/authservice/packages) + and push it to an accessible image registry (e.g. Docker Hub). + See the ["Using the authservice docker image" section in the README.md](https://github.com/istio-ecosystem/authservice/blob/master/README.md#using-the-authservice-docker-image) + for more information. diff --git a/bookinfo-example/config/authservice-configmap-template-for-authn.yaml b/bookinfo-example/config/authservice-configmap-template-for-authn.yaml index 580436b6..208820cd 100644 --- a/bookinfo-example/config/authservice-configmap-template-for-authn.yaml +++ b/bookinfo-example/config/authservice-configmap-template-for-authn.yaml @@ -24,12 +24,12 @@ data: { "oidc": { - "authorization_uri": "https://demo.example.change.me/oauth/authorize/change/me", - "token_uri": "https://demo.example.change.me/oauth/token/change/me", - "callback_uri": "https://INGRESS_HOST_CHANGE_ME/productpage/oauth/callback", - "jwks": "{\"keys\":[{\"kty\":\"RSA\",\"e\":\"AQAB\",\"use\":\"sig\",\"kid\":\"sha2-2017-01-20-key\",\"alg\":\"RS256\",\"value\":\"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyH6kYCP29faDAUPKtei3\nV/Zh8eCHyHRDHrD0iosvgHuaakK1AFHjD19ojuPiTQm8r8nEeQtHb6mDi1LvZ03e\nEWxpvWwFfFVtCyBqWr5wn6IkY+ZFXfERLn2NCn6sMVxcFV12sUtuqD+jrW8MnTG7\nhofQqxmVVKKsZiXCvUSzfiKxDgoiRuD3MJSoZ0nQTHVmYxlFHuhTEETuTqSPmOXd\n/xJBVRi5WYCjt1aKRRZEz04zVEBVhVkr2H84qcVJHcfXFu4JM6dg0nmTjgd5cZUN\ncwA1KhK2/Qru9N0xlk9FGD2cvrVCCPWFPvZ1W7U7PBWOSBBH6GergA+dk2vQr7Ho\nlQIDAQAB\n-----END PUBLIC KEY-----\",\"n\":\"AMh-pGAj9vX2gwFDyrXot1f2YfHgh8h0Qx6w9IqLL4B7mmpCtQBR4w9faI7j4k0JvK_JxHkLR2-pg4tS72dN3hFsab1sBXxVbQsgalq-cJ-iJGPmRV3xES59jQp-rDFcXBVddrFLbqg_o61vDJ0xu4aH0KsZlVSirGYlwr1Es34isQ4KIkbg9zCUqGdJ0Ex1ZmMZRR7oUxBE7k6kj5jl3f8SQVUYuVmAo7dWikUWRM9OM1RAVYVZK9h_OKnFSR3H1xbuCTOnYNJ5k44HeXGVDXMANSoStv0K7vTdMZZPRRg9nL61Qgj1hT72dVu1OzwVjkgQR-hnq4APnZNr0K-x6JU\"}]}", - "client_id": "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx_CHANGE_ME", - "client_secret": "xxxxx-xxxx-xxx-xxx-xxx_CHANGE_ME", + "authorization_uri": "https://accounts.google.com/o/oauth2/v2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "callback_uri": "https://localhost:8443/productpage/oauth/callback", + "jwks": "{ \"keys\": [ { \"use\": \"sig\", \"alg\": \"RS256\", \"n\": \"7qnlkR2Ysvik__jqELu5__2Ib4_Pix6NEmEYKY80NyIGBhUQ0QDtijFypOk3cN3aRgb1f3741vQu7PQGMr79J8jM4-sA1A6UQNmfjl-thB5JpdfQrS1n3EpsrPMUvf5w-uBMQnxmiM3hrHgjA107-UxLF_xBG8Vp_EXmZI7y6IfUwTHrNotSpLLBSNH77C8ncFcm9ADsdl-Bav2CjOaef6CpGISCscx2T4LZS6DIafU1M_xYcx3aLET9TojymjZJi2hfZDyF9x_qssrlnxqfgrI71warY8HiXsiZzOTNB6s81Fu9AaxV7YckfLHyvXwOX8lQN53c2IiAuk-T7nf69w\", \"e\": \"AQAB\", \"kty\": \"RSA\", \"kid\": \"0fcc014f22934e47480daf107a340c22bd262b6c\" }, { \"alg\": \"RS256\", \"e\": \"AQAB\", \"kid\": \"462949174f1eedf4f9f9434877be483b324140f5\", \"kty\": \"RSA\", \"n\": \"2BHFUUq8NqZ3pxxi_RJcSIMG5nJoZQ8Nbvf-lW5o7hJ9CmLA4SeUmDL2IVK6CSuskTPj_ohAp_gtOg3PCJvn33grPoJQu38MoMB8kDqA4U-u3A86GGEjWtk6LPo7dEkojZNQkzhZCnEMTuRMtBZXsLWNGJpY3UADA3rxnHnBP1wrSt27iXIE0C6-1N5z00R13r3L0aWC0MuAUgjI2H4dGMr8B3niJ-NjOVPCwG7xSWsCwsSitAuhPGHaDtenB23ZsFJjbuTuiguoSJ9A1qo9kzBOg32xda4derbWasu7Tk8p53PFxXDJGR_h7dM-nsJHl7lAUDqL8zOrf9XXlPTjwQ\", \"use\": \"sig\" } ] }", + "client_id": "YOUR_OIDC_CLIENT_ID", + "client_secret": "YOUR_OIDC_CLIENT_SECRET", "scopes": [], "cookie_name_prefix": "productpage", "id_token": { @@ -38,7 +38,7 @@ data: }, "logout": { "path": "/authservice_logout", - "redirect_uri": "https:///some/logout/path" + "redirect_uri": "https://localhost:8443/some/logout/path" } } } diff --git a/bookinfo-example/config/bookinfo-gateway.yaml b/bookinfo-example/config/bookinfo-gateway.yaml index 4a7ac795..f54a545f 100644 --- a/bookinfo-example/config/bookinfo-gateway.yaml +++ b/bookinfo-example/config/bookinfo-gateway.yaml @@ -19,9 +19,7 @@ spec: - "*" tls: mode: SIMPLE - serverCertificate: /etc/istio/ingressgateway-certs/tls.crt # pre-req: generate a k8s secret containing these cert files - privateKey: /etc/istio/ingressgateway-certs/tls.key - + credentialName: ingress-tls-cert --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService diff --git a/bookinfo-example/config/bookinfo-with-authservice-template.yaml b/bookinfo-example/config/bookinfo-with-authservice-template.yaml index 633019f8..97a686d9 100644 --- a/bookinfo-example/config/bookinfo-with-authservice-template.yaml +++ b/bookinfo-example/config/bookinfo-with-authservice-template.yaml @@ -266,7 +266,8 @@ spec: ports: - containerPort: 9080 - name: authservice # authservice needs to be deployed in the sample Pod as the productpage - image: # Manually docker pull the latest authservice image from https://github.com/istio-ecosystem/authservice/packages and push it to your own image registry (e.g. Docker Hub), and use it here. (The Github Package Registry does not work with k8s yet until this issue is fixed and released: https://github.com/kubernetes-sigs/kind/issues/870) + # TODO(incfly): change to a proper project wide container registry. + image: gcr.io/jianfeih-images-pub/authservice/authservice:0.4.1 # Manually docker pull the latest authservice image from https://github.com/istio-ecosystem/authservice/packages and push it to your own image registry (e.g. Docker Hub), and use it here. (The Github Package Registry does not work with k8s yet until this issue is fixed and released: https://github.com/kubernetes-sigs/kind/issues/870) imagePullPolicy: Always ports: - containerPort: 10003 diff --git a/bookinfo-example/config/productpage-external-authz-envoyfilter-sidecar.yaml b/bookinfo-example/config/productpage-external-authz-envoyfilter-sidecar.yaml index f32e6003..f300e75c 100644 --- a/bookinfo-example/config/productpage-external-authz-envoyfilter-sidecar.yaml +++ b/bookinfo-example/config/productpage-external-authz-envoyfilter-sidecar.yaml @@ -25,7 +25,7 @@ spec: filter: name: "envoy.http_connection_manager" subFilter: - name: "envoy.filters.http.jwt_authn" + name: "envoy.filters.http.router" # simplify to not require add jwt policy for now. patch: operation: INSERT_BEFORE value: diff --git a/bookinfo-example/scripts/generate-self-signed-certs-for-ingress-gateway.sh b/bookinfo-example/scripts/generate-self-signed-certs-for-ingress-gateway.sh index de7c7036..e48657a3 100755 --- a/bookinfo-example/scripts/generate-self-signed-certs-for-ingress-gateway.sh +++ b/bookinfo-example/scripts/generate-self-signed-certs-for-ingress-gateway.sh @@ -2,14 +2,14 @@ set -eu -ingress_host=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}') - # Generate certs using openssl -openssl req -outform PEM -out /tmp/key.crt.pem -new -keyout /tmp/key.pem -newkey rsa:2048 -batch -nodes -x509 -subj "/CN=${ingress_host}" -days 365 +openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \ + -days 365 -nodes -subj '/CN=localhost' # upload the certs by creating a k8s secret -kubectl create -n istio-system secret tls istio-ingressgateway-certs --key /tmp/key.pem --cert /tmp/key.crt.pem +kubectl create -n istio-system secret tls ingress-tls-cert --key=key.pem \ + --cert=cert.pem # make sure the secret is correctly created echo; echo; echo "Verify that the secret is created:" -kubectl get secret --all-namespaces | grep istio-ingressgateway-certs +kubectl get secret -nistio-system | grep ingress-tls-cert diff --git a/src/filters/filter_chain.cc b/src/filters/filter_chain.cc index 5ce5a624..3139c3d6 100644 --- a/src/filters/filter_chain.cc +++ b/src/filters/filter_chain.cc @@ -65,10 +65,12 @@ std::unique_ptr FilterChainImpl::New() { "only one filter of type \"oidc\" is allowed in a chain"); } + auto jwks_keys = google::jwt_verify::Jwks::createFrom( + filter.oidc().jwks(), google::jwt_verify::Jwks::Type::JWKS); + spdlog::debug("status for jwks parsing: {}, {}", __func__, + google::jwt_verify::getStatusString(jwks_keys->getStatus())); auto token_request_parser = std::make_shared( - google::jwt_verify::Jwks::createFrom( - filter.oidc().jwks(), google::jwt_verify::Jwks::Type::JWKS)); - + std::move(jwks_keys)); auto session_string_generator = std::make_shared(); From c31ccd5a275f50bbb4eed8904c8b0ad2879ec1f9 Mon Sep 17 00:00:00 2001 From: Jianfei Hu Date: Fri, 13 Aug 2021 01:08:32 +0000 Subject: [PATCH 2/6] revert envoyfilter change. Signed-off-by: Jianfei Hu --- .../config/productpage-external-authz-envoyfilter-sidecar.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookinfo-example/config/productpage-external-authz-envoyfilter-sidecar.yaml b/bookinfo-example/config/productpage-external-authz-envoyfilter-sidecar.yaml index f300e75c..f32e6003 100644 --- a/bookinfo-example/config/productpage-external-authz-envoyfilter-sidecar.yaml +++ b/bookinfo-example/config/productpage-external-authz-envoyfilter-sidecar.yaml @@ -25,7 +25,7 @@ spec: filter: name: "envoy.http_connection_manager" subFilter: - name: "envoy.filters.http.router" # simplify to not require add jwt policy for now. + name: "envoy.filters.http.jwt_authn" patch: operation: INSERT_BEFORE value: From c90ea6fa7d660a0d13d82ff974a2b193b2487cac Mon Sep 17 00:00:00 2001 From: Jianfei Hu Date: Fri, 13 Aug 2021 18:42:47 +0000 Subject: [PATCH 3/6] remove push. Signed-off-by: Jianfei Hu --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index abfb744f..20626a06 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ compose: docker-compose up --build docker: build - rm -rf build_release && mkdir -p build_release && cp -r bazel-bin/ build_release && docker build . -f build/Dockerfile.runner -t $(IMAGE) && docker push $(IMAGE) + rm -rf build_release && mkdir -p build_release && cp -r bazel-bin/ build_release && docker build . -f build/Dockerfile.runner -t $(IMAGE) docker-from-scratch: docker build -f build/Dockerfile.builder -t authservice:$(USER) . From b96acd13671aa789bc90b25b17a132357c4b491a Mon Sep 17 00:00:00 2001 From: Jianfei Hu Date: Fri, 13 Aug 2021 20:48:09 +0000 Subject: [PATCH 4/6] example of beta authn,authz and separate service. Signed-off-by: Jianfei Hu --- .../config/authservice-standalone.yaml | 47 +++++++++++++++++++ .../config/ext-authz-productpage.yaml | 34 ++++++++++++++ .../config/idtoken-authn-authz.yaml | 27 +++++++++++ 3 files changed, 108 insertions(+) create mode 100644 bookinfo-example/config/authservice-standalone.yaml create mode 100644 bookinfo-example/config/ext-authz-productpage.yaml create mode 100644 bookinfo-example/config/idtoken-authn-authz.yaml diff --git a/bookinfo-example/config/authservice-standalone.yaml b/bookinfo-example/config/authservice-standalone.yaml new file mode 100644 index 00000000..0da81e91 --- /dev/null +++ b/bookinfo-example/config/authservice-standalone.yaml @@ -0,0 +1,47 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: authservice + # TODO(incfly): change to istio-system when the config map is also updated to that namespace. + # namespace: istio-system + labels: + app: authservice +spec: + replicas: 1 # you can scale up productpage as long as session affinity is enabled via a DestinationRule (see ./config/bookinfo-gateway.yaml) + selector: + matchLabels: + app: authservice + template: + metadata: + labels: + app: authservice + spec: + serviceAccountName: bookinfo-productpage + volumes: + - name: bookinfo-authservice-configmap-volume # declare the volume containing the authservice ConfigMap + configMap: + name: bookinfo-authservice-configmap + containers: + - name: authservice # authservice needs to be deployed in the sample Pod as the productpage + # TODO(incfly): change to a proper project wide container registry. + image: gcr.io/jianfeih-images-pub/authservice/authservice:0.4.1 # Manually docker pull the latest authservice image from https://github.com/istio-ecosystem/authservice/packages and push it to your own image registry (e.g. Docker Hub), and use it here. (The Github Package Registry does not work with k8s yet until this issue is fixed and released: https://github.com/kubernetes-sigs/kind/issues/870) + imagePullPolicy: Always + ports: + - containerPort: 10003 + volumeMounts: + - name: bookinfo-authservice-configmap-volume # mount the volume containing the authservice ConfigMap + mountPath: /etc/authservice +--- +apiVersion: v1 +kind: Service +metadata: + name: authservice + # namespace: istio-system + labels: + app: authservice +spec: + ports: + - port: 10003 + name: grpc + selector: + app: authservice \ No newline at end of file diff --git a/bookinfo-example/config/ext-authz-productpage.yaml b/bookinfo-example/config/ext-authz-productpage.yaml new file mode 100644 index 00000000..8ee25852 --- /dev/null +++ b/bookinfo-example/config/ext-authz-productpage.yaml @@ -0,0 +1,34 @@ +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: ext-authz +spec: + selector: + matchLabels: + app: productpage + action: CUSTOM + provider: + # The provider name must match the extension provider defined in the mesh config. + # You can also replace this with sample-ext-authz-http to test the other external authorizer definition. + name: sample-ext-authz-grpc + rules: + - to: + - operation: + notPaths: ["/public"] # enable all except /public paths. +--- +# Istio requires the external authz provider to be available in the service registry. +# See https://github.com/istio/istio/issues/34622. +apiVersion: networking.istio.io/v1beta1 +kind: ServiceEntry +metadata: + name: authz-svc +spec: + hosts: + - ext.authz.local # not used + ports: + - number: 10003 + name: grpc-ext + protocol: grpc + resolution: STATIC + endpoints: + - address: 127.0.0.1 \ No newline at end of file diff --git a/bookinfo-example/config/idtoken-authn-authz.yaml b/bookinfo-example/config/idtoken-authn-authz.yaml new file mode 100644 index 00000000..23e1c629 --- /dev/null +++ b/bookinfo-example/config/idtoken-authn-authz.yaml @@ -0,0 +1,27 @@ +apiVersion: security.istio.io/v1beta1 +kind: RequestAuthentication +metadata: + name: google-idtoken +spec: + selector: + matchLabels: + app: productpage + jwtRules: + - issuer: "https://accounts.google.com" + jwksUri: "https://www.googleapis.com/oauth2/v3/certs" + forwardOriginalToken: true +--- +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: google-idtoken +spec: + selector: + matchLabels: + app: productpage + action: ALLOW + rules: + - when: + - key: request.auth.claims[iss] + values: + - "https://accounts.google.com" \ No newline at end of file From b6a1e5354eab5a4ba996ebe4cf4643e26c9f901b Mon Sep 17 00:00:00 2001 From: Jianfei Hu Date: Sat, 14 Aug 2021 06:06:28 +0000 Subject: [PATCH 5/6] Helm-ize authservice config. Clarified some expectations on identity provider config and settings. Setup instructions are simplified because of Helm. Also provide config sample as standalone authservice. The in-pod-container mode can be added later. Signed-off-by: Jianfei Hu Signed-off-by: Jianfei Hu --- bookinfo-example/.gitignore | 2 + bookinfo-example/README.md | 80 +++++-- bookinfo-example/auth.yaml | 211 ++++++++++++++++++ bookinfo-example/authservice/.helmignore | 23 ++ bookinfo-example/authservice/Chart.yaml | 24 ++ .../authservice/templates/config.yaml | 48 ++++ .../authservice/templates/deployment.yaml | 46 ++++ .../authservice/templates/ext-authz.yaml | 34 +++ .../authservice/templates/gateway.yaml | 71 ++++++ bookinfo-example/authservice/values.yaml | 11 + ...uthz.yaml => productpage-authn-authz.yaml} | 6 +- src/filters/filter_chain.cc | 8 +- 12 files changed, 538 insertions(+), 26 deletions(-) create mode 100644 bookinfo-example/.gitignore create mode 100644 bookinfo-example/auth.yaml create mode 100644 bookinfo-example/authservice/.helmignore create mode 100644 bookinfo-example/authservice/Chart.yaml create mode 100644 bookinfo-example/authservice/templates/config.yaml create mode 100644 bookinfo-example/authservice/templates/deployment.yaml create mode 100644 bookinfo-example/authservice/templates/ext-authz.yaml create mode 100644 bookinfo-example/authservice/templates/gateway.yaml create mode 100644 bookinfo-example/authservice/values.yaml rename bookinfo-example/config/{idtoken-authn-authz.yaml => productpage-authn-authz.yaml} (84%) diff --git a/bookinfo-example/.gitignore b/bookinfo-example/.gitignore new file mode 100644 index 00000000..9622ab76 --- /dev/null +++ b/bookinfo-example/.gitignore @@ -0,0 +1,2 @@ +key.pem +cert.pem diff --git a/bookinfo-example/README.md b/bookinfo-example/README.md index 7eece42d..6096e575 100644 --- a/bookinfo-example/README.md +++ b/bookinfo-example/README.md @@ -4,42 +4,84 @@ This doc shows how to integrate Authservice into an Istio system deployed on Kub This demo uses the [Istio Bookinfo sample application](https://istio.io/docs/examples/bookinfo/). -This demo takes advantage of an Istio feature set that gives the ability to inject http filters on -Sidecars. This feature set was released in Istio 1.3.0. +This demo takes relies on Istio [external authorization provider](https://istio.io/latest/docs/tasks/security/authorization/authz-custom/), released since 1.9. -Things needed before starting: - -- A Kubernetes cluster that is compatible with Istio 1.3 or newer -- An OIDC provider configured to support Authorization Code grant type. The urls and credentials for this -provider will be needed to configure Authservice. - ### Pre-requisites: -1. Download Istio 1.9 or greater. For example: +1. Prepare your OIDC provider configuration. In our example, we use Google as identity provider. +Follow [instructions](https://developers.google.com/identity/protocols/oauth2/openid-connect) to +create one. - [`scripts/download-istio-1.4.sh`](scripts/download-istio-1.4.sh) + ```shell + export OIDC_CLIENT_ID="" + export OIDC_CLIENT_SECRET="" + ``` -1. Install Istio and enable sidecar injection for the namespace where services will be deployed. For example, - one could install the Istio demo like this: +1. Install Istio for 1.9 or later. - [`scripts/install-istio.sh`](scripts/install-istio.sh) - -1. If certs signed by a known CA cannot be obtained, generate self signed certs for the ingress gateway. For example: + ```shell + istioctl install -y + kubectl label namespace default istio-injection=enabled --overwrite + ``` - [`scripts/generate-self-signed-certs-for-ingress-gateway.sh`](scripts/generate-self-signed-certs-for-ingress-gateway.sh) +1. In our example, we use a self signed certificate at localhost for easy setup. +This is used to terminate HTTPS at the ingress gateway since OIDC requires client callback +URI to be hosted on a protected endpoint. -1. Configure the Istio mesh config with an [external authorization provider](https://istio.io/latest/docs/tasks/security/authorization/authz-custom/) as `sample-ext-authz-grpc`. + ```shell + bash ./scripts/generate-self-signed-certs-for-ingress-gateway.sh + ``` +1. Configure the Istio mesh config with an [external authorization provider](https://istio.io/latest/docs/tasks/security/authorization/authz-custom/). + + ```shell + kubectl edit cm -n istio-system + ``` + ```yaml data: mesh: |- extensionProviders: - - name: "sample-ext-authz-grpc" + - name: "authservice-grpc" envoyExtAuthzGrpc: - service: ext.authz.local + service: authservice.default.svc.cluster.local port: "10003" ``` +1. Install authservice via Helm. + + + ```shell + helm template authservice \ + --set oidc.clientID=${OIDC_CLIENT_ID} \ + --set oidc.clientSecret=${OIDC_CLIENT_SECRET} \ + | kubectl apply -f - + ``` + +1. Access product page via port-forwarding at local host. + + ```shell + kubectl port-forward service/istio-ingressgateway 8443:443 -n istio-system + ``` + + At your browser visit the page at https://localhost:8443/productpage. + +### Further Protect via RequestAuthentication and Authorization Policy + +Istio native RequestAuthentication and Authorization policy can be used configure which end user +can access specific apps, at specific paths. For example, you can apply the sample configuration +to only allow authenticated request to access productpage service. + +```shell +kubectl apply -f ./config/idtoken-authn-authz.yaml +``` + +## Configure OIDC at Ingress Gateway + +TODO(incfly): write it up with sample config and setup. + +## :warning: The REST documnetation needs updates. + ## Deploy Bookinfo Using the Authservice for Token Acquisition (Sidecar integration) The goal of these steps is the protect the `productpage` service with OIDC authentication provided by the mesh. diff --git a/bookinfo-example/auth.yaml b/bookinfo-example/auth.yaml new file mode 100644 index 00000000..5ac1f49f --- /dev/null +++ b/bookinfo-example/auth.yaml @@ -0,0 +1,211 @@ +--- +# Source: authservice/templates/config.yaml +kind: ConfigMap +apiVersion: v1 +metadata: + name: authservice +data: + config.json: | + { + "listen_address": "127.0.0.1", + "listen_port": "10003", + "log_level": "trace", + "threads": 8, + "chains": [ + { + "name": "idp_filter_chain", + "filters": [ + { + "oidc": + { + "authorization_uri": "https://accounts.google.com/o/oauth2/v2/auth", + "token_uri": "https://oauth2.googleapis.com/token ", + "callback_uri": "https://localhost:8443/productpage/oauth/callback", + "jwks": "{ \"keys\": [ { \"use\": \"sig\", \"alg\": \"RS256\", \"n\": \"7qnlkR2Ysvik__jqELu5__2Ib4_Pix6NEmEYKY80NyIGBhUQ0QDtijFypOk3cN3aRgb1f3741vQu7PQGMr79J8jM4-sA1A6UQNmfjl-thB5JpdfQrS1n3EpsrPMUvf5w-uBMQnxmiM3hrHgjA107-UxLF_xBG8Vp_EXmZI7y6IfUwTHrNotSpLLBSNH77C8ncFcm9ADsdl-Bav2CjOaef6CpGISCscx2T4LZS6DIafU1M_xYcx3aLET9TojymjZJi2hfZDyF9x_qssrlnxqfgrI71warY8HiXsiZzOTNB6s81Fu9AaxV7YckfLHyvXwOX8lQN53c2IiAuk-T7nf69w\", \"e\": \"AQAB\", \"kty\": \"RSA\", \"kid\": \"0fcc014f22934e47480daf107a340c22bd262b6c\" }, { \"alg\": \"RS256\", \"e\": \"AQAB\", \"kid\": \"462949174f1eedf4f9f9434877be483b324140f5\", \"kty\": \"RSA\", \"n\": \"2BHFUUq8NqZ3pxxi_RJcSIMG5nJoZQ8Nbvf-lW5o7hJ9CmLA4SeUmDL2IVK6CSuskTPj_ohAp_gtOg3PCJvn33grPoJQu38MoMB8kDqA4U-u3A86GGEjWtk6LPo7dEkojZNQkzhZCnEMTuRMtBZXsLWNGJpY3UADA3rxnHnBP1wrSt27iXIE0C6-1N5z00R13r3L0aWC0MuAUgjI2H4dGMr8B3niJ-NjOVPCwG7xSWsCwsSitAuhPGHaDtenB23ZsFJjbuTuiguoSJ9A1qo9kzBOg32xda4derbWasu7Tk8p53PFxXDJGR_h7dM-nsJHl7lAUDqL8zOrf9XXlPTjwQ\", \"use\": \"sig\" } ] }", + "client_id": "159575789034-27l81afqk927eg7urur2etntg91rv8on.apps.googleusercontent.com", + "client_secret": "5GHnk4Fs94x13Oif4hKhYV2d", + "scopes": [], + "cookie_name_prefix": "productpage", + "id_token": { + "preamble": "Bearer", + "header": "Authorization" + }, + "logout": { + "path": "/authservice_logout", + "redirect_uri": "https://localhost:8443/some/logout/path" + } + } + } + ] + } + ] + } +--- +# Source: authservice/templates/deployment.yaml +apiVersion: v1 +kind: Service +metadata: + name: authservice + # namespace: istio-system + labels: + app: authservice +spec: + ports: + - port: 10003 + name: grpc + selector: + app: authservice +--- +# Source: authservice/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: authservice + # TODO(incfly): change to istio-system when the config map is also updated to that namespace. + # namespace: istio-system + labels: + app: authservice +spec: + replicas: 1 # you can scale up productpage as long as session affinity is enabled via a DestinationRule (see ./config/bookinfo-gateway.yaml) + selector: + matchLabels: + app: authservice + template: + metadata: + labels: + app: authservice + spec: + volumes: + - name: authservice-config # declare the volume containing the authservice ConfigMap + configMap: + name: authservice + containers: + - name: authservice # authservice needs to be deployed in the sample Pod as the productpage + # TODO(incfly): change to a proper project wide container registry. + image: gcr.io/jianfeih-images-pub/authservice/authservice:0.4.1 # Manually docker pull the latest authservice image from https://github.com/istio-ecosystem/authservice/packages and push it to your own image registry (e.g. Docker Hub), and use it here. (The Github Package Registry does not work with k8s yet until this issue is fixed and released: https://github.com/kubernetes-sigs/kind/issues/870) + imagePullPolicy: Always + ports: + - containerPort: 10003 + volumeMounts: + - name: authservice-config # mount the volume containing the authservice ConfigMap + mountPath: /etc/authservice +--- +# Source: authservice/templates/config.yaml +# +# A ConfigMap which contains the configuration of the authservice. +# In bookinfo-with-authservice-template.yaml the authservice container is created +# with this ConfigMap volume mounted inside the container at /etc/authservice, which +# is the location where the authservice expects the file to exist. +# +--- +# Source: authservice/templates/gateway.yaml +# +# A simple example of a gateway for the bookinfo app. +# +--- +# Source: authservice/templates/ext-authz.yaml +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: ext-authz +spec: + selector: + matchLabels: + app: productpage + action: CUSTOM + provider: + # The provider name must match the extension provider defined in the mesh config. + name: authservice.default.svc.cluster.local + rules: + - to: + - operation: + notPaths: ["/public"] # enable all except /public paths. +--- +# Source: authservice/templates/gateway.yaml +# Add a DestinationRule to enable session affinity, which ensures that the requests from the same user-agent reach +# the same instance of productpage, and hence, the same instance of Sidecar and Authservice. This is required when you +# deploy multiple instances of productpage because Authservice currently only supports in-memory session storage. +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: bookinfo-dest-rule +spec: + host: productpage.default.svc.cluster.local + trafficPolicy: + loadBalancer: + consistentHash: + httpCookie: + name: bookinfo-session-affinity-cookie + ttl: 0s +--- +# Source: authservice/templates/gateway.yaml +apiVersion: networking.istio.io/v1alpha3 +kind: Gateway +metadata: + name: bookinfo-gateway +spec: + selector: + istio: ingressgateway # use istio default controller + servers: + - port: + number: 443 + name: https-443 + protocol: HTTPS + hosts: + - "*" + tls: + mode: SIMPLE + credentialName: ingress-tls-cert +--- +# Source: authservice/templates/ext-authz.yaml +# TODO(incfly): enable if else check for including this only for sidecar mode. +# Istio requires the external authz provider to be available in the service registry. +# See https://github.com/istio/istio/issues/34622. +apiVersion: networking.istio.io/v1beta1 +kind: ServiceEntry +metadata: + name: authz-svc +spec: + hosts: + - ext.authz.local # not used + ports: + - number: 10003 + name: grpc-ext + protocol: grpc + resolution: STATIC + endpoints: + - address: 127.0.0.1 +--- +# Source: authservice/templates/gateway.yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: bookinfo +spec: + hosts: + - "*" + gateways: + - bookinfo-gateway + http: + - match: + - uri: + # Allow the Authentication Request Callback to get routed to productpage so it can be intercepted by the authservice + prefix: /productpage/oauth + - uri: + # Allow the authservice logout request to get routed to productpage so it can be intercepted by the authservice + exact: /authservice_logout + - uri: + exact: /productpage + - uri: + prefix: /static + - uri: + exact: /login + - uri: + exact: /logout + - uri: + prefix: /api/v1/ + route: + - destination: + host: productpage + port: + number: 9080 diff --git a/bookinfo-example/authservice/.helmignore b/bookinfo-example/authservice/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/bookinfo-example/authservice/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/bookinfo-example/authservice/Chart.yaml b/bookinfo-example/authservice/Chart.yaml new file mode 100644 index 00000000..f0dfc75d --- /dev/null +++ b/bookinfo-example/authservice/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: authservice +description: A Helm chart for Istio Authservice. + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.4.1" diff --git a/bookinfo-example/authservice/templates/config.yaml b/bookinfo-example/authservice/templates/config.yaml new file mode 100644 index 00000000..e8bbdda8 --- /dev/null +++ b/bookinfo-example/authservice/templates/config.yaml @@ -0,0 +1,48 @@ +# +# A ConfigMap which contains the configuration of the authservice. +# In bookinfo-with-authservice-template.yaml the authservice container is created +# with this ConfigMap volume mounted inside the container at /etc/authservice, which +# is the location where the authservice expects the file to exist. +# + +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: authservice +data: + config.json: | + { + "listen_address": "127.0.0.1", + "listen_port": "10003", + "log_level": "trace", + "threads": 8, + "chains": [ + { + "name": "idp_filter_chain", + "filters": [ + { + "oidc": + { + "authorization_uri": "{{ .Values.oidc.authorizationURI }}", + "token_uri": "{{ .Values.oidc.tokenURI }} ", + "callback_uri": "https://localhost:8443/productpage/oauth/callback", + "jwks": "{ \"keys\": [ { \"use\": \"sig\", \"alg\": \"RS256\", \"n\": \"7qnlkR2Ysvik__jqELu5__2Ib4_Pix6NEmEYKY80NyIGBhUQ0QDtijFypOk3cN3aRgb1f3741vQu7PQGMr79J8jM4-sA1A6UQNmfjl-thB5JpdfQrS1n3EpsrPMUvf5w-uBMQnxmiM3hrHgjA107-UxLF_xBG8Vp_EXmZI7y6IfUwTHrNotSpLLBSNH77C8ncFcm9ADsdl-Bav2CjOaef6CpGISCscx2T4LZS6DIafU1M_xYcx3aLET9TojymjZJi2hfZDyF9x_qssrlnxqfgrI71warY8HiXsiZzOTNB6s81Fu9AaxV7YckfLHyvXwOX8lQN53c2IiAuk-T7nf69w\", \"e\": \"AQAB\", \"kty\": \"RSA\", \"kid\": \"0fcc014f22934e47480daf107a340c22bd262b6c\" }, { \"alg\": \"RS256\", \"e\": \"AQAB\", \"kid\": \"462949174f1eedf4f9f9434877be483b324140f5\", \"kty\": \"RSA\", \"n\": \"2BHFUUq8NqZ3pxxi_RJcSIMG5nJoZQ8Nbvf-lW5o7hJ9CmLA4SeUmDL2IVK6CSuskTPj_ohAp_gtOg3PCJvn33grPoJQu38MoMB8kDqA4U-u3A86GGEjWtk6LPo7dEkojZNQkzhZCnEMTuRMtBZXsLWNGJpY3UADA3rxnHnBP1wrSt27iXIE0C6-1N5z00R13r3L0aWC0MuAUgjI2H4dGMr8B3niJ-NjOVPCwG7xSWsCwsSitAuhPGHaDtenB23ZsFJjbuTuiguoSJ9A1qo9kzBOg32xda4derbWasu7Tk8p53PFxXDJGR_h7dM-nsJHl7lAUDqL8zOrf9XXlPTjwQ\", \"use\": \"sig\" } ] }", + "client_id": "{{ .Values.oidc.clientID }}", + "client_secret": "{{ .Values.oidc.clientSecret }}", + "scopes": [], + "cookie_name_prefix": "productpage", + "id_token": { + "preamble": "Bearer", + "header": "Authorization" + }, + "logout": { + "path": "/authservice_logout", + "redirect_uri": "https://localhost:8443/some/logout/path" + } + } + } + ] + } + ] + } diff --git a/bookinfo-example/authservice/templates/deployment.yaml b/bookinfo-example/authservice/templates/deployment.yaml new file mode 100644 index 00000000..8c2606ab --- /dev/null +++ b/bookinfo-example/authservice/templates/deployment.yaml @@ -0,0 +1,46 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: authservice + # TODO(incfly): change to istio-system when the config map is also updated to that namespace. + # namespace: istio-system + labels: + app: authservice +spec: + replicas: 1 # you can scale up productpage as long as session affinity is enabled via a DestinationRule (see ./config/bookinfo-gateway.yaml) + selector: + matchLabels: + app: authservice + template: + metadata: + labels: + app: authservice + spec: + volumes: + - name: authservice-config # declare the volume containing the authservice ConfigMap + configMap: + name: authservice + containers: + - name: authservice # authservice needs to be deployed in the sample Pod as the productpage + # TODO(incfly): change to a proper project wide container registry. + image: gcr.io/jianfeih-images-pub/authservice/authservice:0.4.1 # Manually docker pull the latest authservice image from https://github.com/istio-ecosystem/authservice/packages and push it to your own image registry (e.g. Docker Hub), and use it here. (The Github Package Registry does not work with k8s yet until this issue is fixed and released: https://github.com/kubernetes-sigs/kind/issues/870) + imagePullPolicy: Always + ports: + - containerPort: 10003 + volumeMounts: + - name: authservice-config # mount the volume containing the authservice ConfigMap + mountPath: /etc/authservice +--- +apiVersion: v1 +kind: Service +metadata: + name: authservice + # namespace: istio-system + labels: + app: authservice +spec: + ports: + - port: 10003 + name: grpc + selector: + app: authservice diff --git a/bookinfo-example/authservice/templates/ext-authz.yaml b/bookinfo-example/authservice/templates/ext-authz.yaml new file mode 100644 index 00000000..318660ab --- /dev/null +++ b/bookinfo-example/authservice/templates/ext-authz.yaml @@ -0,0 +1,34 @@ +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: ext-authz +spec: + selector: + matchLabels: + app: productpage + action: CUSTOM + provider: + # The provider name must match the extension provider defined in the mesh config. + name: authservice-grpc + rules: + - to: + - operation: + notPaths: ["/public"] # enable all except /public paths. +--- +# TODO(incfly): enable if else check for including this only for sidecar mode. +# Istio requires the external authz provider to be available in the service registry. +# See https://github.com/istio/istio/issues/34622. +apiVersion: networking.istio.io/v1beta1 +kind: ServiceEntry +metadata: + name: authz-svc +spec: + hosts: + - ext.authz.local # not used + ports: + - number: 10003 + name: grpc-ext + protocol: grpc + resolution: STATIC + endpoints: + - address: 127.0.0.1 \ No newline at end of file diff --git a/bookinfo-example/authservice/templates/gateway.yaml b/bookinfo-example/authservice/templates/gateway.yaml new file mode 100644 index 00000000..f54a545f --- /dev/null +++ b/bookinfo-example/authservice/templates/gateway.yaml @@ -0,0 +1,71 @@ +# +# A simple example of a gateway for the bookinfo app. +# + +--- +apiVersion: networking.istio.io/v1alpha3 +kind: Gateway +metadata: + name: bookinfo-gateway +spec: + selector: + istio: ingressgateway # use istio default controller + servers: + - port: + number: 443 + name: https-443 + protocol: HTTPS + hosts: + - "*" + tls: + mode: SIMPLE + credentialName: ingress-tls-cert +--- +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: bookinfo +spec: + hosts: + - "*" + gateways: + - bookinfo-gateway + http: + - match: + - uri: + # Allow the Authentication Request Callback to get routed to productpage so it can be intercepted by the authservice + prefix: /productpage/oauth + - uri: + # Allow the authservice logout request to get routed to productpage so it can be intercepted by the authservice + exact: /authservice_logout + - uri: + exact: /productpage + - uri: + prefix: /static + - uri: + exact: /login + - uri: + exact: /logout + - uri: + prefix: /api/v1/ + route: + - destination: + host: productpage + port: + number: 9080 +--- +# Add a DestinationRule to enable session affinity, which ensures that the requests from the same user-agent reach +# the same instance of productpage, and hence, the same instance of Sidecar and Authservice. This is required when you +# deploy multiple instances of productpage because Authservice currently only supports in-memory session storage. +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: bookinfo-dest-rule +spec: + host: productpage.default.svc.cluster.local + trafficPolicy: + loadBalancer: + consistentHash: + httpCookie: + name: bookinfo-session-affinity-cookie + ttl: 0s \ No newline at end of file diff --git a/bookinfo-example/authservice/values.yaml b/bookinfo-example/authservice/values.yaml new file mode 100644 index 00000000..0878a920 --- /dev/null +++ b/bookinfo-example/authservice/values.yaml @@ -0,0 +1,11 @@ +image: + repository: gcr.io/jianfeih-images-pub/authservice/authservice:0.4.1 + +oidc: + idpURL: https://account.google.com + authorizationURI: "https://accounts.google.com/o/oauth2/v2/auth" + tokenURI: "https://oauth2.googleapis.com/token" + clientID: your-client-id + clientSecret: your-client-secret + jwks: "json-string-to-bep-pasted-here" + diff --git a/bookinfo-example/config/idtoken-authn-authz.yaml b/bookinfo-example/config/productpage-authn-authz.yaml similarity index 84% rename from bookinfo-example/config/idtoken-authn-authz.yaml rename to bookinfo-example/config/productpage-authn-authz.yaml index 23e1c629..ef44f6a3 100644 --- a/bookinfo-example/config/idtoken-authn-authz.yaml +++ b/bookinfo-example/config/productpage-authn-authz.yaml @@ -1,7 +1,7 @@ apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: - name: google-idtoken + name: productpage-auth spec: selector: matchLabels: @@ -14,7 +14,7 @@ spec: apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: - name: google-idtoken + name: productpage-auth spec: selector: matchLabels: @@ -24,4 +24,4 @@ spec: - when: - key: request.auth.claims[iss] values: - - "https://accounts.google.com" \ No newline at end of file + - "https://accounts.google.com" diff --git a/src/filters/filter_chain.cc b/src/filters/filter_chain.cc index 3139c3d6..e3a61365 100644 --- a/src/filters/filter_chain.cc +++ b/src/filters/filter_chain.cc @@ -66,11 +66,11 @@ std::unique_ptr FilterChainImpl::New() { } auto jwks_keys = google::jwt_verify::Jwks::createFrom( - filter.oidc().jwks(), google::jwt_verify::Jwks::Type::JWKS); + filter.oidc().jwks(), google::jwt_verify::Jwks::Type::JWKS); spdlog::debug("status for jwks parsing: {}, {}", __func__, - google::jwt_verify::getStatusString(jwks_keys->getStatus())); - auto token_request_parser = std::make_shared( - std::move(jwks_keys)); + google::jwt_verify::getStatusString(jwks_keys->getStatus())); + auto token_request_parser = + std::make_shared(std::move(jwks_keys)); auto session_string_generator = std::make_shared(); From 8938103fae8e465f819c0a9352bf0533b8ead8c6 Mon Sep 17 00:00:00 2001 From: Jianfei Hu Date: Mon, 16 Aug 2021 20:43:10 +0000 Subject: [PATCH 6/6] remove auth.yaml and update readme.md Signed-off-by: Jianfei Hu --- bookinfo-example/README.md | 4 +- bookinfo-example/auth.yaml | 211 ------------------------------------- 2 files changed, 2 insertions(+), 213 deletions(-) delete mode 100644 bookinfo-example/auth.yaml diff --git a/bookinfo-example/README.md b/bookinfo-example/README.md index 8e60f187..0bb45f34 100644 --- a/bookinfo-example/README.md +++ b/bookinfo-example/README.md @@ -46,8 +46,8 @@ URI to be hosted on a protected endpoint. extensionProviders: - name: "authservice-grpc" envoyExtAuthzGrpc: - service: authservice.default.svc.cluster.local - port: "10003" + service: authservice.default.svc.cluster.local + port: "10003" ``` 1. Install authservice via Helm. diff --git a/bookinfo-example/auth.yaml b/bookinfo-example/auth.yaml deleted file mode 100644 index 5ac1f49f..00000000 --- a/bookinfo-example/auth.yaml +++ /dev/null @@ -1,211 +0,0 @@ ---- -# Source: authservice/templates/config.yaml -kind: ConfigMap -apiVersion: v1 -metadata: - name: authservice -data: - config.json: | - { - "listen_address": "127.0.0.1", - "listen_port": "10003", - "log_level": "trace", - "threads": 8, - "chains": [ - { - "name": "idp_filter_chain", - "filters": [ - { - "oidc": - { - "authorization_uri": "https://accounts.google.com/o/oauth2/v2/auth", - "token_uri": "https://oauth2.googleapis.com/token ", - "callback_uri": "https://localhost:8443/productpage/oauth/callback", - "jwks": "{ \"keys\": [ { \"use\": \"sig\", \"alg\": \"RS256\", \"n\": \"7qnlkR2Ysvik__jqELu5__2Ib4_Pix6NEmEYKY80NyIGBhUQ0QDtijFypOk3cN3aRgb1f3741vQu7PQGMr79J8jM4-sA1A6UQNmfjl-thB5JpdfQrS1n3EpsrPMUvf5w-uBMQnxmiM3hrHgjA107-UxLF_xBG8Vp_EXmZI7y6IfUwTHrNotSpLLBSNH77C8ncFcm9ADsdl-Bav2CjOaef6CpGISCscx2T4LZS6DIafU1M_xYcx3aLET9TojymjZJi2hfZDyF9x_qssrlnxqfgrI71warY8HiXsiZzOTNB6s81Fu9AaxV7YckfLHyvXwOX8lQN53c2IiAuk-T7nf69w\", \"e\": \"AQAB\", \"kty\": \"RSA\", \"kid\": \"0fcc014f22934e47480daf107a340c22bd262b6c\" }, { \"alg\": \"RS256\", \"e\": \"AQAB\", \"kid\": \"462949174f1eedf4f9f9434877be483b324140f5\", \"kty\": \"RSA\", \"n\": \"2BHFUUq8NqZ3pxxi_RJcSIMG5nJoZQ8Nbvf-lW5o7hJ9CmLA4SeUmDL2IVK6CSuskTPj_ohAp_gtOg3PCJvn33grPoJQu38MoMB8kDqA4U-u3A86GGEjWtk6LPo7dEkojZNQkzhZCnEMTuRMtBZXsLWNGJpY3UADA3rxnHnBP1wrSt27iXIE0C6-1N5z00R13r3L0aWC0MuAUgjI2H4dGMr8B3niJ-NjOVPCwG7xSWsCwsSitAuhPGHaDtenB23ZsFJjbuTuiguoSJ9A1qo9kzBOg32xda4derbWasu7Tk8p53PFxXDJGR_h7dM-nsJHl7lAUDqL8zOrf9XXlPTjwQ\", \"use\": \"sig\" } ] }", - "client_id": "159575789034-27l81afqk927eg7urur2etntg91rv8on.apps.googleusercontent.com", - "client_secret": "5GHnk4Fs94x13Oif4hKhYV2d", - "scopes": [], - "cookie_name_prefix": "productpage", - "id_token": { - "preamble": "Bearer", - "header": "Authorization" - }, - "logout": { - "path": "/authservice_logout", - "redirect_uri": "https://localhost:8443/some/logout/path" - } - } - } - ] - } - ] - } ---- -# Source: authservice/templates/deployment.yaml -apiVersion: v1 -kind: Service -metadata: - name: authservice - # namespace: istio-system - labels: - app: authservice -spec: - ports: - - port: 10003 - name: grpc - selector: - app: authservice ---- -# Source: authservice/templates/deployment.yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: authservice - # TODO(incfly): change to istio-system when the config map is also updated to that namespace. - # namespace: istio-system - labels: - app: authservice -spec: - replicas: 1 # you can scale up productpage as long as session affinity is enabled via a DestinationRule (see ./config/bookinfo-gateway.yaml) - selector: - matchLabels: - app: authservice - template: - metadata: - labels: - app: authservice - spec: - volumes: - - name: authservice-config # declare the volume containing the authservice ConfigMap - configMap: - name: authservice - containers: - - name: authservice # authservice needs to be deployed in the sample Pod as the productpage - # TODO(incfly): change to a proper project wide container registry. - image: gcr.io/jianfeih-images-pub/authservice/authservice:0.4.1 # Manually docker pull the latest authservice image from https://github.com/istio-ecosystem/authservice/packages and push it to your own image registry (e.g. Docker Hub), and use it here. (The Github Package Registry does not work with k8s yet until this issue is fixed and released: https://github.com/kubernetes-sigs/kind/issues/870) - imagePullPolicy: Always - ports: - - containerPort: 10003 - volumeMounts: - - name: authservice-config # mount the volume containing the authservice ConfigMap - mountPath: /etc/authservice ---- -# Source: authservice/templates/config.yaml -# -# A ConfigMap which contains the configuration of the authservice. -# In bookinfo-with-authservice-template.yaml the authservice container is created -# with this ConfigMap volume mounted inside the container at /etc/authservice, which -# is the location where the authservice expects the file to exist. -# ---- -# Source: authservice/templates/gateway.yaml -# -# A simple example of a gateway for the bookinfo app. -# ---- -# Source: authservice/templates/ext-authz.yaml -apiVersion: security.istio.io/v1beta1 -kind: AuthorizationPolicy -metadata: - name: ext-authz -spec: - selector: - matchLabels: - app: productpage - action: CUSTOM - provider: - # The provider name must match the extension provider defined in the mesh config. - name: authservice.default.svc.cluster.local - rules: - - to: - - operation: - notPaths: ["/public"] # enable all except /public paths. ---- -# Source: authservice/templates/gateway.yaml -# Add a DestinationRule to enable session affinity, which ensures that the requests from the same user-agent reach -# the same instance of productpage, and hence, the same instance of Sidecar and Authservice. This is required when you -# deploy multiple instances of productpage because Authservice currently only supports in-memory session storage. -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: bookinfo-dest-rule -spec: - host: productpage.default.svc.cluster.local - trafficPolicy: - loadBalancer: - consistentHash: - httpCookie: - name: bookinfo-session-affinity-cookie - ttl: 0s ---- -# Source: authservice/templates/gateway.yaml -apiVersion: networking.istio.io/v1alpha3 -kind: Gateway -metadata: - name: bookinfo-gateway -spec: - selector: - istio: ingressgateway # use istio default controller - servers: - - port: - number: 443 - name: https-443 - protocol: HTTPS - hosts: - - "*" - tls: - mode: SIMPLE - credentialName: ingress-tls-cert ---- -# Source: authservice/templates/ext-authz.yaml -# TODO(incfly): enable if else check for including this only for sidecar mode. -# Istio requires the external authz provider to be available in the service registry. -# See https://github.com/istio/istio/issues/34622. -apiVersion: networking.istio.io/v1beta1 -kind: ServiceEntry -metadata: - name: authz-svc -spec: - hosts: - - ext.authz.local # not used - ports: - - number: 10003 - name: grpc-ext - protocol: grpc - resolution: STATIC - endpoints: - - address: 127.0.0.1 ---- -# Source: authservice/templates/gateway.yaml -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: bookinfo -spec: - hosts: - - "*" - gateways: - - bookinfo-gateway - http: - - match: - - uri: - # Allow the Authentication Request Callback to get routed to productpage so it can be intercepted by the authservice - prefix: /productpage/oauth - - uri: - # Allow the authservice logout request to get routed to productpage so it can be intercepted by the authservice - exact: /authservice_logout - - uri: - exact: /productpage - - uri: - prefix: /static - - uri: - exact: /login - - uri: - exact: /logout - - uri: - prefix: /api/v1/ - route: - - destination: - host: productpage - port: - number: 9080