Reputation: 6111
My application deployed on openshift has url as https://host:port/app/v1/hello/ I am using ServiceAccount as Oauth client and the provider is Openshift, so I should be redirected to Openshift login page for Authorization.
We have configured openshift/oauth-proxy and it works great. https://github.com/openshift/oauth-proxy/
Now further we have requirement of Path based routing, like if URL has /app/v1 then redirect to Service1 and if /app/v2 then to Service2
Here is the working example of my configuration,
`kind: Template
apiVersion: v1
metadata:
name: deployment-template
objects:
- apiVersion: v1
kind: ServiceAccount
metadata:
name: my-service-account
annotations:
serviceaccounts.openshift.io/oauth-redirectreference.first: '{"kind":"OAuthRedirectReference","apiVersion":"v1","reference":{"kind":"Route","name":"my-route"}}'
- apiVersion: v1
kind: Service
metadata:
name: my-service
annotations:
service.alpha.openshift.io/serving-cert-secret-name: proxy-tls
spec:
selector:
app: spring-boot-docker-openshift-hello-world
ports:
- name: api
protocol: TCP
port: 443 #Port the service listens on.
targetPort: 8443 #Port on the backing pods to which the service forwards connections.
- apiVersion: v1
kind: Route
metadata:
name: my-route
spec:
port:
targetPort: api
path: "/"
to:
kind: Service
name: my-service
tls:
termination: Reencrypt
- apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
labels:
app: spring-boot-docker-openshift-hello-world
version: 0.0.1-SNAPSHOT.1.dev
name: spring-boot-docker-openshift-hello-world
spec:
replicas: 1
selector:
app: spring-boot-docker-openshift-hello-world
strategy:
rollingParams:
timeoutSeconds: 3600
type: Rolling
template:
metadata:
labels:
app: spring-boot-docker-openshift-hello-world
version: 0.0.1-SNAPSHOT.1.dev
spec:
serviceAccount: my-service-account
serviceAccountName: my-service-account
containers:
- name: spring-boot-docker-openshift-hello-world
env:
- name: KUBERNETES_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: pokarjm/spring-boot-docker-openshift-hello-world:0.0.1-SNAPSHOT.1.dev
imagePullPolicy: IfNotPresent
securityContext:
privileged: false
ports:
- containerPort: 8080
protocol: TCP
- name: oauth-proxy
image: openshift/oauth-proxy:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8443
name: public
args:
- --https-address=:8443
- --provider=openshift
- --openshift-service-account=my-service-account
- --upstream=http://localhost:8080
- --tls-cert=/etc/tls/private/tls.crt
- --tls-key=/etc/tls/private/tls.key
- --cookie-secret-file=/etc/proxy/secret/session_secret
- --openshift-ca=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
- --openshift-sar={"namespace":"spring-boot-docker-openshift-hello-world","resource":"services","name":"my-service","verb":"get"}
- --request-logging=true
volumeMounts:
- mountPath: /etc/tls/private
name: proxy-tls
readOnly: true
- mountPath: /etc/proxy/secret
name: oauth-proxy-secret
readOnly: true
volumes:
- name: proxy-tls
secret:
defaultMode: 420
secretName: proxy-tls
- name: oauth-proxy-secret
secret:
defaultMode: 420
secretName: oauth-proxy-secret
triggers:
- type: ConfigChange
`
Now to support path based routing, that is map the request /app/v1 to Service1, I just added the Path in route like below,
- apiVersion: v1
kind: Route
metadata:
name: my-route
spec:
port:
targetPort: api
path: "/app/v1"
to:
kind: Service
name: my-service
tls:
termination: Reencrypt
but with this changes I can see a initial sign in page like below
but after clicking the button above instead of getting the openshift login page, I see below,
If I change the path in route to path: "/" it works and shows login screen. Appreciate any help on fixing path based routing in openshift/oauth-proxy.
Upvotes: 1
Views: 1682
Reputation: 5042
Try adding something like --proxy-prefix=/app/v1
, to your oauth proxy container.
Eg:
[...]
args:
- --https-address=:8443
- --provider=openshift
- --proxy-prefix=/app/v1
- --openshift-service-account=my-service-account
[...]
Otherwise, the oauth-proxy would assume the application it is serving lies at the root of your Route, breaking the login callback redirection.
Now, regarding your question in comments, I'm no sure I got it all myself, I don't have an OpenShift cluster to test this with, ... take it with a pinch of salt, edits welcome, if anyone can get this right.
As far as I understand and recall:
openshift-service-account
, reads those out of /var/run/secrets/kubernetes.io/serviceaccount/
). You could instead use client-id=system:serviceaccount:$ns:$sa
and client-secret-file=/var/run/secrets/kubernetes.io/serviceaccount/token
, if detection somehow doesn't work.serviceaccounts.openshift.io/oauth-redirectreference
annotation (though there's another way to do this, with OauthClient, which I'm less familiar with), matching the client requested application URL. On successful match, SP replies to oauth-proxy with some ephemeral tokenproxy-prefix
, the oauth-proxy redirects unauthenticated users to the Oauth login portal, with some encoded callback URL as a GET paramopenshift-sar
was defined, oauth-proxy proceeds with some additional check ensuring client is authorized, otherwise any user may log in
In OpenShift context, the initial token requests is done using the login-url
param, which defaults to kubernetes.default.svc/oauth/authorize
, though in some cases (not sure to remember, some unusual networkpolicies), you may want to force use your OpenShift console FQDN instead.
The token redemption is done through the redeem-url
which defaults to kubernetes.default.svc/oauth/token
. Again, you could use your public console FQDN here, if SDN otherwise denies this traffic.
So, how is proxy-prefix coming into the picture: only required for your oauth-proxy to build the proper callback URL, for the login form to send you back to the proper sub-path of your application.
And the OAuthRedirectReference is mainly used by OpenShift making sure the client requesting a token is indeed meant to authenticated clients for a given Route. In your case, only matching a FQDN, although I think that in addition to serviceaccounts.openshift.io/oauth-redirectreference.$name: {"kind": ...}
, you may also set something like serviceaccounts.openshift.io/oauth-redirecturi.name: my-path
Upvotes: 2