Skip to content

feat(openid-connect): make session_secret support configurable#8068

Merged
spacewander merged 10 commits into
apache:masterfrom
bzp2010:fix-oidc-multi-worker
Oct 17, 2022
Merged

feat(openid-connect): make session_secret support configurable#8068
spacewander merged 10 commits into
apache:masterfrom
bzp2010:fix-oidc-multi-worker

Conversation

@bzp2010

@bzp2010 bzp2010 commented Oct 11, 2022

Copy link
Copy Markdown
Contributor

Description

The current OIDC plugin for APISIX uses lua-resty-session, which requires encryption of the session, but we do not provide a default secret nor do we allow users to configure it directly.

Therefore, according to the implementation principle in lua-resty-session, if no secret configuration is provided, it will generate one at initialization, yes, one at each worker, and they are all different.

When a client uses a short connection or traffic passes through a load balancing component, it may request to a different worker each time, which causes decryption and hash verification failures.

I think if we can allow users to set session secret through plugin configuration, we can solve this problem.

Checklist

  • I have explained the need for this PR and the problem it solves
  • I have explained the changes or the new features added to this PR
  • I have added tests corresponding to this change
  • I have updated the documentation to reflect this change
  • I have verified that this change is backward compatible (If not, please discuss on the APISIX mailing list first)

@bzp2010 bzp2010 self-assigned this Oct 11, 2022
@bzp2010 bzp2010 changed the title feat: make session_secret support configurable feat(openid-connect): make session_secret support configurable Oct 11, 2022
@bzp2010
bzp2010 marked this pull request as ready for review October 13, 2022 06:41
tzssangglass
tzssangglass previously approved these changes Oct 13, 2022
| set_userinfo_header | boolean | False | true | | When set to true and the UserInfo object is available, sets it in the `X-Userinfo` request header. |
| set_refresh_token_header | boolean | False | false | | When set to true and a refresh token object is available, sets it in the `X-Refresh-Token` request header. |
| session | object | False | | | When bearer_only is set to false, openid-connect will use Authorization Code flow to authenticate on the IDP, so you need to set the session-related configuration. |
| session.secret | string | True | Automatic generation | 16 or more characters | The key used for session encrypt and HMAC operation. |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we apply the "16 or more characters" check in the schema?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think it's best to do that. Let me modify it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

spacewander
spacewander previously approved these changes Oct 14, 2022
Comment thread t/plugin/openid-connect2.t Outdated
end,
},
{
name = "sanity (bearer_only = false, user-set secret, less than 16 charactors)",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

charactors

Typo?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I have fixed it.

@mkyc

mkyc commented Dec 15, 2022

Copy link
Copy Markdown

Should this also be implemented in 2.15 versions since it's LTS? I can confirm that this problematic behaviour exists on 2.15.1 when gateway is behind AWS ALB Ingress.

@tzssangglass

Copy link
Copy Markdown
Member

Should this also be implemented in 2.15 versions since it's LTS? I can confirm that this problematic behaviour exists on 2.15.1 when gateway is behind AWS ALB Ingress.

#6792 (comment) would works for you?

@mkyc

mkyc commented Dec 16, 2022

Copy link
Copy Markdown

@tzssangglass nice! Following workaround in APISIX helm chart values fixes problem in 2.15.1:

configurationSnippet:
  httpSrv: |
    set $session_secret 0123456789a5bac9bb3c868ec8b202e93;

@MirtoBusico

Copy link
Copy Markdown

@tzssangglass nice! Following workaround in APISIX helm chart values fixes problem in 2.15.1:

configurationSnippet:
  httpSrv: |
    set $session_secret 0123456789a5bac9bb3c868ec8b202e93;

Hi all,
I tried to use the workaround.

Now in my values.yaml for apisix helm chart I have:

# Custom configuration snippet.
configurationSnippet:
  main: |

  httpStart: |

  httpEnd: |

  httpSrv: |
    set $session_secret 0123456789a5bac9bb3c868ec8b202e93;

  httpAdmin: |

  stream: |

# Observability configuration.

Still I get a "openid-connect exits with http status code 500" error from the openid-connect plugin.

2022/12/24 12:44:45 [warn] 47#47: *581337 [lua] v3.lua:716: request_chunk(): http://apisix-etcd.apisix.svc.cluster.local:2379: failed to parse domain: failed to parse domain. Retrying, context: ngx.timer
2022/12/24 12:47:11 [warn] 47#47: *666008 [lua] v3.lua:716: request_chunk(): http://apisix-etcd.apisix.svc.cluster.local:2379: failed to parse domain: failed to parse domain. Retrying, context: ngx.timer
2022/12/24 12:48:22 [error] 50#50: *673065 [lua] openidc.lua:1100: authenticate(): state from argument: 75f1ea8eb72acd29e847e4afe36ca426 does not match state restored from session: a1072f4e1facdf0e90714bbd6163ea0e, client: 127.0.0.6, server: _, request: "GET /*?state=75f1ea8eb72acd29e847e4afe36ca426&session_state=aff4d9a9-1641-455d-b368-6f13c2925c32&code=9de7dc09-e3db-4507-a4be-51c4b57de1aa.aff4d9a9-1641-455d-b368-6f13c2925c32.84a0adb8-9534-4db9-9e55-7675c11e5b76 HTTP/1.0", host: "apisix.h.net"
2022/12/24 12:48:22 [error] 50#50: *673065 [lua] openid-connect.lua:315: phase_func(): OIDC authentication failed: state from argument does not match state restored from session, client: 127.0.0.6, server: _, request: "GET /*?state=75f1ea8eb72acd29e847e4afe36ca426&session_state=aff4d9a9-1641-455d-b368-6f13c2925c32&code=9de7dc09-e3db-4507-a4be-51c4b57de1aa.aff4d9a9-1641-455d-b368-6f13c2925c32.84a0adb8-9534-4db9-9e55-7675c11e5b76 HTTP/1.0", host: "apisix.h.net"
2022/12/24 12:48:22 [warn] 50#50: *673065 [lua] plugin.lua:934: run_plugin(): openid-connect exits with http status code 500, client: 127.0.0.6, server: _, request: "GET /*?state=75f1ea8eb72acd29e847e4afe36ca426&session_state=aff4d9a9-1641-455d-b368-6f13c2925c32&code=9de7dc09-e3db-4507-a4be-51c4b57de1aa.aff4d9a9-1641-455d-b368-6f13c2925c32.84a0adb8-9534-4db9-9e55-7675c11e5b76 HTTP/1.0", host: "apisix.h.net"

What I'm doing wrong?

@mehmetcuneyit

Copy link
Copy Markdown

@tzssangglass nice! Following workaround in APISIX helm chart values fixes problem in 2.15.1:

configurationSnippet:
  httpSrv: |
    set $session_secret 0123456789a5bac9bb3c868ec8b202e93;

Hi all, I tried to use the workaround.

Now in my values.yaml for apisix helm chart I have:

# Custom configuration snippet.
configurationSnippet:
  main: |

  httpStart: |

  httpEnd: |

  httpSrv: |
    set $session_secret 0123456789a5bac9bb3c868ec8b202e93;

  httpAdmin: |

  stream: |

# Observability configuration.

Still I get a "openid-connect exits with http status code 500" error from the openid-connect plugin.

2022/12/24 12:44:45 [warn] 47#47: *581337 [lua] v3.lua:716: request_chunk(): http://apisix-etcd.apisix.svc.cluster.local:2379: failed to parse domain: failed to parse domain. Retrying, context: ngx.timer
2022/12/24 12:47:11 [warn] 47#47: *666008 [lua] v3.lua:716: request_chunk(): http://apisix-etcd.apisix.svc.cluster.local:2379: failed to parse domain: failed to parse domain. Retrying, context: ngx.timer
2022/12/24 12:48:22 [error] 50#50: *673065 [lua] openidc.lua:1100: authenticate(): state from argument: 75f1ea8eb72acd29e847e4afe36ca426 does not match state restored from session: a1072f4e1facdf0e90714bbd6163ea0e, client: 127.0.0.6, server: _, request: "GET /*?state=75f1ea8eb72acd29e847e4afe36ca426&session_state=aff4d9a9-1641-455d-b368-6f13c2925c32&code=9de7dc09-e3db-4507-a4be-51c4b57de1aa.aff4d9a9-1641-455d-b368-6f13c2925c32.84a0adb8-9534-4db9-9e55-7675c11e5b76 HTTP/1.0", host: "apisix.h.net"
2022/12/24 12:48:22 [error] 50#50: *673065 [lua] openid-connect.lua:315: phase_func(): OIDC authentication failed: state from argument does not match state restored from session, client: 127.0.0.6, server: _, request: "GET /*?state=75f1ea8eb72acd29e847e4afe36ca426&session_state=aff4d9a9-1641-455d-b368-6f13c2925c32&code=9de7dc09-e3db-4507-a4be-51c4b57de1aa.aff4d9a9-1641-455d-b368-6f13c2925c32.84a0adb8-9534-4db9-9e55-7675c11e5b76 HTTP/1.0", host: "apisix.h.net"
2022/12/24 12:48:22 [warn] 50#50: *673065 [lua] plugin.lua:934: run_plugin(): openid-connect exits with http status code 500, client: 127.0.0.6, server: _, request: "GET /*?state=75f1ea8eb72acd29e847e4afe36ca426&session_state=aff4d9a9-1641-455d-b368-6f13c2925c32&code=9de7dc09-e3db-4507-a4be-51c4b57de1aa.aff4d9a9-1641-455d-b368-6f13c2925c32.84a0adb8-9534-4db9-9e55-7675c11e5b76 HTTP/1.0", host: "apisix.h.net"

What I'm doing wrong?

Change 'set $session_secret' -> 'set $session_redis_password' , the lua-resty-session lib updated this field

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants