Method Not Allowed 405 for registration and login

Hi there,

I have a complete implementation of self-service using Kratos. All working on local, unfortunately, there are some I believe misconfiguration on our staging that becomes a blocker now.

Behind the Nginx, I’m using Oathkeeper as a proxy, and we have a lot of services:

-
  id: "ory:kratos:public"
  upstream:
    preserve_host: true
    url: "http://kratos:4433"
    strip_path: /ory/kratos/public
  match:
    url: "http://www.domain.com/ory/kratos/public/<.*>"
    methods:
      - GET
      - POST
      - PUT
      - DELETE
      - PATCH
  authenticators:
    -
      handler: noop
  authorizer:
    handler: allow
  mutators:
    - handler: noop
-
  id: "ory:login:public"
  upstream:
    preserve_host: true
    url: "http://login:4435"
    strip_path: /ory
  match:
    url: "http://www.domain.com/ory/<(?!settings|kratos/public).*>"
    methods:
      - GET
  authenticators:
    - handler: anonymous
  authorizer:
    handler: allow
  mutators:
    - handler: noop
-
  id: "ory:login:protected"
  upstream:
    preserve_host: true
    url: "http://login:4435"
    strip_path: /ory
  match:
    url: "http://www.domain.com/ory/<(settings).*>"
    methods:
      - GET
  authenticators:
    - handler: cookie_session
  authorizer:
    handler: allow
  mutators:
    - handler: id_token
  errors:
    - handler: redirect
      config:
        to: http://www.domain.com/auth

The URL matching using regexp.

The strange thing is when login, register instead of sending a POST method, it is sending a GET method, which is why I believe I constantlyu get a Method Not Allowed error seen in the browser and in the kratos log I got this:

time=2020-11-30T04:53:22Z level=info msg=started handling request func=github.com/ory/x/reqlog.(*Middleware).ServeHTTP file=/go/pkg/mod/github.com/ory/[email protected]/reqlog/middleware.go:131 method=GET name=public#http://www.domain.com/ory/kratos/public/ remote=10.0.1.4:55478 request=/self-service/login/methods/password?flow=db251993-7507-49ca-9985-ab686fb3d911
time=2020-11-30T04:53:22Z level=info msg=completed handling request func=github.com/ory/x/reqlog.(*Middleware).ServeHTTP file=/go/pkg/mod/github.com/ory/[email protected]/reqlog/middleware.go:139 method=GET name=public#http://www.domain.com/ory/kratos/public/ remote=10.0.1.4:55478 request=/self-service/login/methods/password?flow=db251993-7507-49ca-9985-ab686fb3d911 status=405 text_status=Method Not Allowed took=94.414µs

And seem nothing wrong in the rendered form, copy-pasted from browser inspection:

action=“http://www.domain.com/ory/kratos/public/self-service/login/methods/password?flow=db251993-7507-49ca-9985-ab686fb3d911” method=“POST”

As I said, nothing wrong with local, this only happens on the staging server.

Technical Requirements:

  • Kratos version 0.5.3-alpha.1
  • Database MySQL
  • Local: docker-compose almost similar to quickstart
  • Staging: docker swarm mode

Turns out the behaviour of the POST method becomes GET is not by Kratos or Oathkeeper. And I want to keep this forum focus on Ory environment, so I will only share the Ory approach to fix this issue if one of you encounter the same problem.

It is simply changing this block:

-
  id: "ory:kratos:public"
  upstream:
    preserve_host: true
    url: "http://kratos:4433"
    strip_path: /ory/kratos/public
  match:
    url: "http://www.domain.com/ory/kratos/public/<.*>"
    ...

into this:

-
  id: "ory:kratos:public"
  upstream:
    preserve_host: true
    url: "http://kratos:4433"
    strip_path: /ory/kratos/public
  match:
    url: "<http|https>://www.domain.com/ory/kratos/public/<.*>"
    ...

Yeah the difference is only in the <http|https> pattern

1 Like