manusa / isotope-mail

Isotope Mail Client
https://blog.marcnuri.com/isotope-mail-client-introduction/
Apache License 2.0
233 stars 43 forks source link

Server returning "Unauthorized" on every request #346

Open kafeinnet opened 4 years ago

kafeinnet commented 4 years ago

Hi, I'm experimenting with isotope and traefik2 in a docker swarm environment. So far I'm not able to get any working request from the server. It only responds "Unauthorized".

Here is the relevant part of the stack :

  isotope-server:
    image: marcnuri/isotope:server-latest
    deploy:
      labels:
        - traefik.docker.network=frontend
        - traefik.enable=true
        - traefik.http.routers.mailapi.entrypoints=http
        - traefik.http.routers.mailapi.rule=Host(`mail.example.org`) && PathPrefix(`/api/`)
        - traefik.http.services.mailapi.loadbalancer.server.port=9010
      placement:
        constraints:
          - node.labels.dc == tls00
    networks:
      - frontend
      - mail

  isotope-client:
    image: marcnuri/isotope:client-latest
    deploy:
      labels:
        - traefik.docker.network=frontend
        - traefik.enable=true
        - traefik.http.routers.mail.entrypoints=http
        - traefik.http.routers.mail.rule=Host(`mail.example.org`)
        - traefik.http.services.mail.loadbalancer.server.port=80
      placement:
        constraints:
          - node.labels.dc == tls00
    networks:
      - frontend

The server only returns this line for every request :

mail_isotope-server.1.kl5apuqtdnij@riesling    | 2020-02-22 13:25:46.008  INFO 1 --- [nio-9010-exec-3] .m.i.a.c.CredentialsAuthenticationFilter : Couldn't authenticate request

I tried to read the code but java or JS are not quite my cup of tea.

\fab

manusa commented 4 years ago

Hi @kafeinnet

The problem is that you're not stripping the /api prefix for isotope-server.

The following Traefik v2 configuration worked for me (check the api-stripprefix Middleware):

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: ingressroutes.traefik.containo.us

spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: IngressRoute
    plural: ingressroutes
    singular: ingressroute
  scope: Namespaced

---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: ingressroutetcps.traefik.containo.us

spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: IngressRouteTCP
    plural: ingressroutetcps
    singular: ingressroutetcp
  scope: Namespaced

---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: middlewares.traefik.containo.us

spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: Middleware
    plural: middlewares
    singular: middleware
  scope: Namespaced

---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: tlsoptions.traefik.containo.us

spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: TLSOption
    plural: tlsoptions
    singular: tlsoption
  scope: Namespaced

---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: traefikservices.traefik.containo.us

spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: TraefikService
    plural: traefikservices
    singular: traefikservice
  scope: Namespaced

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller

rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses/status
    verbs:
      - update
  - apiGroups:
      - traefik.containo.us
    resources:
      - middlewares
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - traefik.containo.us
    resources:
      - ingressroutes
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - traefik.containo.us
    resources:
      - ingressroutetcps
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - traefik.containo.us
    resources:
      - tlsoptions
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - traefik.containo.us
    resources:
      - traefikservices
    verbs:
      - get
      - list
      - watch

---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller

roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: traefik-ingress-controller
subjects:
  - kind: ServiceAccount
    name: traefik-ingress-controller
    namespace: default
---
apiVersion: v1
kind: Service
metadata:
  name: traefik
spec:
  type: NodePort
  ports:
    - protocol: TCP
      name: web
      port: 8000
    - protocol: TCP
      name: admin
      port: 8080
    - protocol: TCP
      name: websecure
      port: 4443
  selector:
    app: traefik

---
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: default
  name: traefik-ingress-controller

---
kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: default
  name: traefik
  labels:
    app: traefik

spec:
  replicas: 1
  selector:
    matchLabels:
      app: traefik
  template:
    metadata:
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik-ingress-controller
      containers:
        - name: traefik
          image: traefik:v2.1
          args:
            - --api.insecure
            - --accesslog
            - --entrypoints.web.Address=:8000
            - --entrypoints.websecure.Address=:4443
            - --providers.kubernetescrd
          ports:
            - name: web
              containerPort: 8000
            - name: websecure
              containerPort: 4443
            - name: admin
              containerPort: 8080

---
apiVersion: v1
kind: Secret
metadata:
  name: isotope-secrets
type: Opaque
data:
  encryptionPassword: U2VjcmV0SzhzUGFzd29yZA==
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: isotope-server
  labels:
    app: isotope
    component: server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: isotope
      component: server
      version: latest
  template:
    metadata:
      labels:
        app: isotope
        component: server
        version: latest
    spec:
      containers:
        - name: isotope-server
          image: marcnuri/isotope:server-latest
          imagePullPolicy: Always
          ports:
            - containerPort: 9010
          env:
            - name: ENCRYPTION_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: isotope-secrets
                  key: encryptionPassword
          livenessProbe:
            httpGet:
              path: /actuator/health
              port: 9010
            failureThreshold: 6
            periodSeconds: 5
          # Use startupProbe instead if your k8s version supports it
            initialDelaySeconds: 60
          readinessProbe:
            httpGet:
              path: /actuator/health
              port: 9010
            failureThreshold: 2
            periodSeconds: 5
#          startupProbe:
#            httpGet:
#              path: /actuator/health
#              port: 9010
#            initialDelaySeconds: 20
#            failureThreshold: 15
#            periodSeconds: 10
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: isotope-client
  labels:
    app: isotope
    component: client
spec:
  replicas: 1
  selector:
    matchLabels:
      app: isotope
      component: client
      version: latest
  template:
    metadata:
      labels:
        app: isotope
        component: client
        version: latest
    spec:
      containers:
        - name: isotope-client
          image: marcnuri/isotope:client-latest
          imagePullPolicy: Always
          ports:
            - containerPort: 80
          livenessProbe:
            httpGet:
              path: /favicon.ico
              port: 80
            failureThreshold: 6
            periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: isotope-server
spec:
  ports:
    - name: http
      targetPort: 9010
      port: 80
  selector:
    app: isotope
    component: server
---
apiVersion: v1
kind: Service
metadata:
  name: isotope-client
spec:
  ports:
    - name: http
      targetPort: 80
      port: 80
  selector:
    app: isotope
    component: client
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: api-stripprefix
spec:
  stripPrefix:
    prefixes:
      - /api
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: isotope-ingress-route
  namespace: default
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`traefik-ui.local`) && PathPrefix(`/`)
    kind: Rule
    services:
    - name: isotope-client
      port: 80
  - match: Host(`traefik-ui.local`) && PathPrefix(`/api`)
    kind: Rule
    services:
    - name: isotope-server
      port: 80
    middlewares:
      - name: api-stripprefix

I'll probably submit a new blog post to update the current instructions for Traefik v1.

kafeinnet commented 4 years ago

Of course ! A stripprefix middleware did the trick and I'm feeling a little dumb now.

Thanks !

purvaldur commented 3 years ago

Hey, sorry if it's not the right place to ask, but I have the same question - however I'm using nginx-ingress as my ingress and I'm experiencing the same issue. I've tried the solution from this stackoverflow answer: https://stackoverflow.com/questions/52923298/remove-routing-path-from-kubernetes-ingress but to no avail. Is there a recommended way to strip the path prefix in the nginx-ingress that'll work with Isotope mail?

If there's not, it's completely fine. I'll see if I can get it working, then paste the solution somewhere for others in my position to hopefully see. I'm just asking here, just in case.