By Jingze Dai, Developer of Alibaba Cloud API Gateway, Member of the Higress Open Source Community
As businesses grow, the number of systems they use also increases, leading to a poor user experience due to the need for frequent logins across different systems. Single Sign-On (SSO) is designed to address this issue. SSO allows a single login to grant access to all systems, eliminating the need for individual logins for each system.
Currently, common SSO implementation approaches include:
OIDC is also widely supported by third-party service providers like Alipay, DingTalk, WeChat, GitHub, and more. For example, the login page of the Sealos application allows third-party logins via GitHub, WeChat, and Google, using OIDC for authentication.
The Higress gateway, which is the entry point for all requests to backend services, can integrate with OIDC to provide a unified authentication service. This means that backend services do not need to implement their own user authentication logic; instead, user identity authentication is handled centrally through the gateway. This simplifies the system architecture, reduces redundant work, and improves security.
Users can configure OIDC authentication at the gateway to achieve fine-grained access control over resources. It also facilitates easy integration with self-managed identity authentication services or other third-party accounts, such as social media, improving business convenience.
Based on this, we developed an OIDC plugin that allows users to implement SSO in the Higress gateway without writing any code.
Deploy a backend sample service in the cluster, such as the Istio Bookinfo example, for testing the OIDC plugin functionality. After deployment, you can use the following command to verify if the deployment is successful.
kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"
Deploy the keycloak authentication service
Quickly deploy the keycloak authentication service using Docker by following the keycloak-getting-started-docker guide. Add a user and create a client.
Note: You need to fill in the Valid redirect URIs, Valid post logout URIs, and Web origins configuration options; otherwise, the OIDC Provider will consider the user's redirect or logout URLs invalid.
Higress service configuration
Create a keycloak fixed address service in the Higress service sources.
Wasm plugin configuration
redirect_url: 'http://foo.bar.com/oauth2/callback'
oidc_issuer_url: 'http://127.0.0.1:9090/realms/myrealm'
client_id: 'XXXXXXXXXXXXXXXX'
client_secret: 'XXXXXXXXXXXXXXXX'
scope: 'openid email'
cookie_secret: 'nqavJrGvRmQxWwGNptLdyUVKcBNZ2b18Guc1n_8DCfY='
service_name: 'keycloak.static'
service_port: 80
service_host: '127.0.0.1:9090'
Access the service page, and if you are not logged in, it will redirect to the login page.
After a successful login, it will redirect back to the service page.
Accessing the logout will redirect to the logout page.
http://foo.bar.com/oauth2/sign_out?rd=http%3A%2F%2F127.0.0.1:9090%2Frealms%2Fmyrealm%2Fprotocol%2Fopenid-connect%2Flogout
Accessing the logout will redirect to the logout page (with the post_logout_redirect_uri parameter to redirect to a specified URI).
http://foo.bar.com/oauth2/sign_out?rd=http%3A%2F%2F127.0.0.1:9090%2Frealms%2Fmyrealm%2Fprotocol%2Fopenid-connect%2Flogout%3Fpost_logout_redirect_uri%3Dhttp%3A%2F%2Ffoo.bar.com%2Ffoo
Configure Alibaba Cloud OAuth applications
Follow the process outlined in Access Alibaba Cloud APIs from a web application to configure the OAuth application.
Higress service configuration
To allow the plugin to access the OIDC service provider, create an Aliyun DNS service in the Higress service sources.
Plugin parameter configuration
redirect_url: 'http://foo.bar.com/oauth2/callback'
provider: aliyun
oidc_issuer_url: 'https://oauth.aliyun.com/'
client_id: 'XXXXXXXXXXXXXXXX'
client_secret: 'XXXXXXXXXXXXXXXX'
scope: 'openid'
cookie_secret: 'nqavJrGvRmQxWwGNptLdyUVKcBNZ2b18Guc1n_8DCfY='
service_name: 'aliyun.dns'
service_port: 443
Access the service page, and if you are not logged in, it will redirect to the login page.
Scanning the QR code for login will redirect to the service page upon successful authentication.
Accessing the logout will redirect to the logout page (after logging out from Alibaba Cloud, it will redirect to the login page).
http://foo.bar.com/oauth2/sign_out?rd=https%3A%2F%2Faccount.aliyun.com%2Flogout%2Flogout.htm
The Istio community has proposed using a Sidecar container for external authorization, such as the mature oauth2-proxy solution mentioned in Istio OIDC Authentication with OAuth2-Proxy. However, this solution has some drawbacks. Firstly, it adds an extra layer of request calls between the external authorization service and the data plane, which can lead to performance degradation. Secondly, the external authorization service consumes CPU and memory resources. Additionally, if users need to configure multiple service providers, they would have to deploy multiple external authorizations, making this solution less flexible.
The existing C++ native OAuth2 Filter developed by the Envoy community can also implement OIDC authentication. The Envoy community's envoy gateway project uses this solution, which is currently under active development. However, there are issues: it does not support the standard OIDC protocol state parameter (Issue 35232), making it vulnerable to CSRF attacks, and it does not support encrypting tokens in cookies (Issue 23508). These security vulnerabilities make the OAuth2 Filter unsuitable for production use.
The open source Higress project plugin development framework supports writing Wasm plugins in various programming languages, including Rust, C++, Golang, and AssemblyScript (a Wasm dialect of TypeScript). Compared with the C++ ecosystem, languages like Rust, Go, and TypeScript have a richer set of open source libraries. Some open source projects that implement OIDC functionality include:
• Golang: oauth2-proxy
• Rust: oauth2-rs
• TypeScript: angular-oauth2-oidc
Among these, the oauth2-proxy project is widely used and validated in the open source community, with the most active community support and frequent updates and improvements. It implements most of the common OIDC service providers and is recommended in the Istio Sidecar container solution. The advantages of the Wasm plugin solution are as follows:
Given these advantages and considering the flexibility and security issues of the first two solutions, the Wasm plugin solution was developed to implement OIDC functionality.
The OIDC plugin is based on the core process of the oauth2-proxy project. Since initiating external requests in Envoy plugins requires asynchronous calls, the synchronous calls in the main flow of the oauth2-proxy project have been modified to asynchronous calls with external services in Envoy. The response is then processed in a callback function. For specific code, refer to the OIDC plugin in Higress. The request response flow of the OIDC plugin is as follows:
1. Simulate a user to access the corresponding service APIs.
curl --url "foo.bar.com/headers"
2. Higress redirects to the OIDC Provider's login page with OIDC authentication parameters such as client_id, response_type, and scope, and sets a CSRF cookie to defend against CSRF attacks.
curl --url "https://dev-o43xb1mz7ya7ach4.us.auth0.com/authorize"\
--url-query "approval_prompt=force" \
--url-query "client_id=YagFqRD9tfNIaac5BamjhsSatjrAnsnZ" \
--url-query "redirect_uri=http%3A%2F%2Ffoo.bar.com%2Foauth2%2Fcallback" \
--url-query "response_type=code" \
--url-query "scope=openid+email+offline_access" \
--url-query "state=nT06xdCqn4IqemzBRV5hmO73U_hCjskrH_VupPqdcdw%3A%2Ffoo" \
--header "Set-Cookie: _oauth2_proxy_csrf=LPruATEDgcdmelr8zScD_ObhsbP4zSzvcgmPlcNDcJpFJ0OvhxP2hFotsU-kZnYxd5KsIjzeIXGTOjf8TKcbTHbDIt-aQoZORXI_0id3qeY0Jt78223DPeJ1xBqa8VO0UiEOUFOR53FGxirJOdKFxaAvxDFb1Ok=|1718962455|V1QGWyjQ4hMNOQ4Jtf17HeQJdVqHdt5d65uraFduMIU=; Path=/; Expires=Fri, 21 Jun 2024 08:06:20 GMT; HttpOnly"
3. The user logs in on the login page.
4. The user is redirected back to Higress with an authorization code and a state parameter to validate the CSRF cookie. The authorization code is used to exchange for a token.
curl --url "http://foo.bar.com/oauth2/callback" \
--url-query "state=nT06xdCqn4IqemzBRV5hmO73U_hCjskrH_VupPqdcdw%3A%2Ffoo" \
--url-query "code=0bdopoS2c2lx95u7iO0OH9kY1TvaEdJHo4lB6CT2_qVFm"
5. The authorization code is used to exchange for id_token and access_token.
curl -X POST \
--url "https://dev-o43xb1mz7ya7ach4.us.auth0.com/oauth/token" \
--data "grant_type=authorization_code" \
--data "client_id=YagFqRD9tfNIaac5BamjhsSatjrAnsnZ" \
--data "client_secret=ekqv5XoZuMFtYms1NszEqRx03qct6BPvGeJUeptNG4y09PrY16BKT9IWezTrrhJJ" \
--data "redirect_uri=http%3A%2F%2Ffoo.bar.com%2Foauth2%2Fcallback" \
--data "code=0bdopoS2c2lx95u7iO0OH9kY1TvaEdJHo4lB6CT2_qVFm" \
The returned request includes the id_token, access_token, and refresh_token for future access_token refreshes.
{
"access_token": "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwiaXNzIjoiaHR0cHM6Ly9kZXYtbzQzeGIxbXo3eWE3YWNoNC51cy5hdXRoMC5jb20vIn0..WP_WRVM-y3fM1sN4.fAQqtKoKZNG9Wj0OhtrMgtsjTJ2J72M2klDRd9SvUKGbiYsZNPmIl_qJUf81D3VIjD59o9xrOOJIzXTgsfFVA2x15g-jBlNh68N7dyhXu9237Tbplweu1jA25IZDSnjitQ3pbf7xJVIfPnWcrzl6uT8G1EP-omFcl6AQprV2FoKFMCGFCgeafuttppKe1a8mpJDj7AFLPs-344tT9mvCWmI4DuoLFh0PiqMMJBByoijRSxcSdXLPxZng84j8JVF7H6mFa-dj-icP-KLy6yvzEaRKz_uwBzQCzgYK434LIpqw_PRuN3ClEsenwRgIsNdVjvKcoAysfoZhmRy9BQaE0I7qTohSBFNX6A.mgGGeeWgugfXcUcsX4T5dQ",
"refresh_token": "GrZ1f2JvzjAZQzSXmyr1ScWbv8aMFBvzAXHBUSiILcDEG",
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Imc1Z1ExSF9ZbTY0WUlvVkQwSVpXTCJ9.eyJlbWFpbCI6IjE2MDExNTYyNjhAcXEuY29tIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJpc3MiOiJodHRwczovL2Rldi1vNDN4YjFtejd5YTdhY2g0LnVzLmF1dGgwLmNvbS8iLCJhdWQiOiJZYWdGcVJEOXRmTklhYWM1QmFtamhzU2F0anJBbnNuWiIsImlhdCI6MTcxOTE5ODYzOCwiZXhwIjoxNzE5MjM0NjM4LCJzdWIiOiJhdXRoMHw2NjVkNzFlNzRjMTMxMTc3YmU2NmU2MDciLCJzaWQiOiJjdDJVOF9ZUS16VDdFOGkwRTNNeUstejc5ZGlWUWhhVSJ9.gfzXKJ0FeqzYqOUDLQHWcUG19IOLqkpLN09xTmIat0umrlGV5VNSumgWH3XJmmwnhdb8AThH3Jf-7kbRJzu4rM-BbGbFTRBTzNHeUajFOFrIgld5VENQ_M_sXHkTp0psWKSr9vF24kmilCfSbvC5lBKjt878ljZ7-xteWuaUYOMUdcJb4DSv0-zjX01sonJxYamTlhji3M4TAW7VwhwqyZt8dBhVSNaRw1wUKj-M1JrBDLyx65sroZtSqVA0udIrqMHEbWYb2de7JjzlqG003HRMzwOm7OXgEd5ZVFqgmBLosgixOU5DJ4A26nlqK92Sp6VqDMRvA-3ym8W_m-wJ_A",
"scope": "openid email offline_access",
"expires_in": 86400,
"token_type": "Bearer"
}
6. The obtained id_token and access_token are encrypted and stored in the Cookie _oauth2_proxy for subsequent user login state validation. The Cookie _oauth2_proxy_csrf is cleared.
"Set-Cookie": [
"_oauth2_proxy_csrf=; Path=/; Expires=Mon, 24 Jun 2024 02:17:39 GMT; HttpOnly",
"_oauth2_proxy=8zM_Pcfpp_gesKFe4SMg08o5Iv0A8WAOQOmG1-vZBbQ56UggYVC0Cu-gFMEoxJZU5q1O5vqRlVBizlLetgVjRCksGVbttwl8tQ7h5YiyIubbbtvF1T4JzLh3QfzUUrwbB-VznOkh8qLbjAhddocecjBt4rMiDyceKXqMr4eO5TUEMx4vHtJYnTYalMeTYhGXk5MNSyrdZX9NnQnkdrCjiOQM13ggwob2nYwhGWaAlgzFSWkgkdtBy2Cl_YMWZ8_gKk9rDX289-JrJyGpr5k9O9RzRhZoY2iE3Mcr8-Q37RTji1Ga22QO-XkAcSaGqY1Qo7jLdmgZTYKC5JvtdLc4rj3vcbveYxU7R3Pt2vEribQjKTh4Sqb0aA03p4cxXyZN4SUfBW1NAOm4JLPUhKJy8frqC9_E0nVqPvpvnacaoQs8WkX2zp75xHoMa3SD6KZhQ5JUiPEiNkOaUsyafLvht6lLkNDhgzW3BP2czoe0DCDBLnsot0jH-qQpMZYkaGr-ZnRKI1OPl1vHls3mao5juOAW1VB2A9aughgc8SJ55IFZpMfFMdHdTDdMqPODkItX2PK44GX-pHeLxkOqrzp3GHtMInpL5QIQlTuux3erm3CG-ntlUE7JBtN2T9LEb8XfIFu58X9_vzMun4JQlje2Thi9_taI_z1DSaTtvNNb54wJfSPwYCCl4OsH-BacVmPQhH6TTZ6gP2Qsm5TR2o1U2D9fuVkSM-OPCG9l3tILambIQwC3vofMW6X8SIFSmhJUDvN7NbwxowBiZ6Y7GJRZlAk_GKDkpsdrdIvC67QqczZFphRVnm6qi-gPO41APCbcO6fgTwyOhbP3RrZZKWSIqWJYhNE3_Sfkf0565H7sC7Hc8XUUjJvP3WnjKS9x7KwzWa-dsUjV3-Q-VNl-rXTguVNAIirYK-qrMNMZGCRcJqcLnUF0V_J2lVmFyVsSlE3t0sDw2xmbkOwDptXFOjQL5Rb4esUMYdCBWFajBfvUtcZEFtYhD0kb6VcbjXO3NCVW5qKh_l9C9SRCc7TG1vcRAqUQlRXHacTGWfcWsuQkCJ3Mp_oWaDxs1GRDykQYxAn5sTICovThWEU2C6o75grWaNrkj5NU-0eHh3ryvxLmGLBOXZV9OQhtKShWmUgywSWMxOHOuZAqdAPULc8KheuGFjXYp-RnCbFYWePJmwzfQw89kSkj1KUZgMYwKEjSz62z2qc9KLczomv76ortQzvo4Hv9kaW6xVuQj5R5Oq6_WMBOqsmUMzcXpxCIOGjcdcZRBc0Fm09Uy9oV1PRqvAE4PGtfyrCaoqILBix8UIww63B07YGwzQ-hAXDysBK-Vca2x7GmGdXsNXXcTgu00bdsjtHZPDBBWGfL3g_rMAXr2vWyvK4CwNjcaPAmrlF3geHPwbIePT0hskBboX1v1bsuhzsai7rGM4r53pnb1ZEoTQDa1B-HyokFgo14XiwME0zE1ifpNzefjpkz1YY2krJlqfCydNwoKaTit4tD2yHlnxAeFF9iIrxzSKErNUFpmyLa7ge7V33vhEH-6k5oBTLE2Q2BrC6aAkLCcPwU9xv_SzBDQPRY0MEYv3kGF03Swo1crRbGh-aifYX9NiHDsmG6r1vAnx0MAOw2Jzuz2x6SSdfBrzlcoWBlrwiZzd9kAKq75n1Uy9uzZ8SRnkBrEZySHBwEbu196VklkRE0jqwC-e3wWNNuviSOfwkVeX-7QdOoO10yw9VK2sW52lFvIEf4chv_ta7bGfAZOWBjpktG6ZLD81SE6A88zpqG2SysSyNMp9hl-umG-5sFsjCn_c9E8bDvwkUOUVb9bNqhBDsZgR0BNPawiOZjmyfhzmwmWf-zgFzfFSV6BvOwNRi3sCOHTsWcuk9NBQ_YK8CpNkVl3WeIBSDfidimuC_QV9UWKs1GPk35ZRkM4zKtLY2JsBFWKaDy_P80TcOzcMBoP8gIBClXZ-WUqfE8s1yyc4jrq-qL1_wJ24ef1O9FktsbyZiDKXw2vnqsT8-g_hCeG-unrT1ZFscf8oNdqczARHX-K4vKH2k3uIqEx1M=|1719199056|2rsgdUIClHNEpxBLlHOVRYup6e4oKensQfljtmn4B80=; Path=/; Expires=Mon, 01 Jul 2024 03:17:36 GMT; HttpOnly"
]
7. The API is accessed with an Authorization header containing the access_token.
curl --url "foo.bar.com/headers"
--header "Authorization: Bearer eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwiaXNzIjoiaHR0cHM6Ly9kZXYtbzQzeGIxbXo3eWE3YWNoNC51cy5hdXRoMC5jb20vIn0..WP_WRVM-y3fM1sN4.fAQqtKoKZNG9Wj0OhtrMgtsjTJ2J72M2klDRd9SvUKGbiYsZNPmIl_qJUf81D3VIjD59o9xrOOJIzXTgsfFVA2x15g-jBlNh68N7dyhXu9237Tbplweu1jA25IZDSnjitQ3pbf7xJVIfPnWcrzl6uT8G1EP-omFcl6AQprV2FoKFMCGFCgeafuttppKe1a8mpJDj7AFLPs-344tT9mvCWmI4DuoLFh0PiqMMJBByoijRSxcSdXLPxZng84j8JVF7H6mFa-dj-icP-KLy6yvzEaRKz_uwBzQCzgYK434LIpqw_PRuN3ClEsenwRgIsNdVjvKcoAysfoZhmRy9BQaE0I7qTohSBFNX6A.mgGGeeWgugfXcUcsX4T5dQ"
8. The backend service retrieves user information based on the access_token and returns the corresponding HTTP response.
{
"email": "******",
"email_verified": false,
"iss": "https://dev-o43xb1mz7ya7ach4.us.auth0.com/",
"aud": "YagFqRD9tfNIaac5BamjhsSatjrAnsnZ",
"iat": 1719198638,
"exp": 1719234638,
"sub": "auth0|665d71e74c131177be66e607",
"sid": "ct2U8_YQ-zT7E8i0E3MyK-z79diVQhaU"
}
This article introduces the open source OIDC Wasm plugin in Higress. Currently, the Wasm plugin in the Higress project supports development in Go, C++, Rust, and AssemblyScript, and more languages will be supported in the future, lowering the threshold for development. Additionally, the Wasm plugin runs in an isolated sandboxed environment, providing higher security. Wasm itself, as a high-performance portable binary instruction format, continues to see new advancements and technological innovations. More features for gateway scenarios can be considered for implementation within Wasm plugins in the future.
The OIDC Wasm plugin described in this article is now available in the Higress project.
505 posts | 48 followers
FollowAlibaba Cloud Community - February 17, 2022
Alibaba Clouder - July 25, 2019
JDP - February 10, 2022
Alibaba Clouder - September 22, 2020
ClouderLouder - July 22, 2020
Alibaba Cloud Community - June 16, 2022
505 posts | 48 followers
FollowMulti-source metrics are aggregated to monitor the status of your business and services in real time.
Learn MoreAPI Gateway provides you with high-performance and high-availability API hosting services to deploy and release your APIs on Alibaba Cloud products.
Learn MoreGet started on cloud with $1. Start your cloud innovation journey here and now.
Learn MoreAccelerate and secure the development, deployment, and management of containerized applications cost-effectively.
Learn MoreMore Posts by Alibaba Cloud Native Community