Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[17.0][PORT] auth_oidc: prompt for account on AAD login #706

Merged
merged 1 commit into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions auth_oidc/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ or

|image2|

- Auth Link Params: Add {'prompt':'select_account'} to the auth link to
get the account selection screen |image3|

Setup for Keycloak
------------------

Expand Down Expand Up @@ -126,6 +129,7 @@ In Odoo, create a new Oauth Provider with the following parameters:
.. |image| image:: https://raw.githubusercontent.com/OCA/server-auth/17.0/auth_oidc/static/description/oauth-microsoft_azure-api_permissions.png
.. |image1| image:: https://raw.githubusercontent.com/OCA/server-auth/17.0/auth_oidc/static/description/oauth-microsoft_azure-optional_claims.png
.. |image2| image:: https://raw.githubusercontent.com/OCA/server-auth/17.0/auth_oidc/static/description/odoo-azure_ad_multitenant.png
.. |image3| image:: https://raw.githubusercontent.com/OCA/server-auth/17.0/auth_oidc/static/description/oauth-microsoft_azure-select_account.png

Usage
=====
Expand Down
7 changes: 7 additions & 0 deletions auth_oidc/controllers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import hashlib
import logging
import secrets
from ast import literal_eval

from werkzeug.urls import url_decode, url_encode

Expand Down Expand Up @@ -43,6 +44,12 @@ def list_providers(self):
if "openid" not in provider["scope"].split():
_logger.error("openid connect scope must contain 'openid'")
params["scope"] = provider["scope"]

# append provider specific auth link params
if provider["auth_link_params"]:
params_upd = literal_eval(provider["auth_link_params"])
params.update(params_upd)

# auth link that the user will click
provider["auth_link"] = "{}?{}".format(
provider["auth_endpoint"], url_encode(params)
Expand Down
2 changes: 2 additions & 0 deletions auth_oidc/data/auth_oauth_data.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
>https://login.microsoftonline.com/organizations/discovery/v2.0/keys</field>
<field name="css_class">fa fa-fw fa-windows</field>
<field name="body">Log in with Microsoft</field>
<field name="auth_link_params">{'prompt':'select_account'}</field>
</record>
<record id="provider_azuread_single" model="auth.oauth.provider">
<field name="name">Azure AD Single Tenant</field>
Expand All @@ -35,5 +36,6 @@
>https://login.microsoftonline.com/{tenant_id}/discovery/v2.0/keys</field>
<field name="css_class">fa fa-fw fa-windows</field>
<field name="body">Log in with Microsoft</field>
<field name="auth_link_params">{'prompt':'select_account'}</field>
</record>
</odoo>
20 changes: 20 additions & 0 deletions auth_oidc/demo/local_keycloak.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,24 @@
name="jwks_uri"
>http://localhost:8080/auth/realms/master/protocol/openid-connect/certs</field>
</record>
<record id="provider_azuread_multi" model="auth.oauth.provider">
<field name="name">Azure AD Multitenant</field>
<field name="flow">id_token_code</field>
<field name="client_id">auth_oidc-test</field>
<field name="enabled">True</field>
<field name="token_map">upn:user_id upn:email</field>
<field
name="auth_endpoint"
>https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize</field>
<field name="scope">profile openid</field>
<field
name="token_endpoint"
>https://login.microsoftonline.com/organizations/oauth2/v2.0/token</field>
<field
name="jwks_uri"
>https://login.microsoftonline.com/organizations/discovery/v2.0/keys</field>
<field name="css_class">fa fa-fw fa-windows</field>
<field name="body">Log in with Microsoft</field>
<field name="auth_link_params">{'prompt':'select_account'}</field>
</record>
</odoo>
4 changes: 4 additions & 0 deletions auth_oidc/models/auth_oauth_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ class AuthOauthProvider(models.Model):
string="Token URL", help="Required for OpenID Connect authorization code flow."
)
jwks_uri = fields.Char(string="JWKS URL", help="Required for OpenID Connect.")
auth_link_params = fields.Char(
help="Additional parameters for the auth link. "
"For example: {'prompt':'select_account'}"
)

@tools.ormcache("self.jwks_uri", "kid")
def _get_keys(self, kid):
Expand Down
4 changes: 4 additions & 0 deletions auth_oidc/readme/CONFIGURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ or

![image](../static/description/odoo-azure_ad_multitenant.png)

- Auth Link Params: Add {'prompt':'select_account'} to the auth link to get the account selection screen
![image](../static/description/oauth-microsoft_azure-select_account.png)


## Setup for Keycloak

Example configuration with OpenID Connect authorization code flow.
Expand Down
15 changes: 11 additions & 4 deletions auth_oidc/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@

/*
:Author: David Goodger ([email protected])
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.

See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
Expand Down Expand Up @@ -274,7 +275,7 @@
margin-left: 2em ;
margin-right: 2em }

pre.code .ln { color: grey; } /* line numbers */
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
Expand All @@ -300,7 +301,7 @@
span.pre {
white-space: pre }

span.problematic {
span.problematic, pre.problematic {
color: red }

span.section-subtitle {
Expand Down Expand Up @@ -448,6 +449,10 @@ <h2><a class="toc-backref" href="#toc-entry-3">Setup for Microsoft Azure</a></h2
<li>replace {tenant_id} in urls with your Azure tenant id</li>
</ul>
<p><img alt="image2" src="https://raw.githubusercontent.com/OCA/server-auth/17.0/auth_oidc/static/description/odoo-azure_ad_multitenant.png" /></p>
<ul class="simple">
<li>Auth Link Params: Add {‘prompt’:’select_account’} to the auth link to
get the account selection screen <img alt="image3" src="https://raw.githubusercontent.com/OCA/server-auth/17.0/auth_oidc/static/description/oauth-microsoft_azure-select_account.png" /></li>
</ul>
</div>
<div class="section" id="setup-for-keycloak">
<h2><a class="toc-backref" href="#toc-entry-4">Setup for Keycloak</a></h2>
Expand Down Expand Up @@ -582,7 +587,9 @@ <h2><a class="toc-backref" href="#toc-entry-20">Contributors</a></h2>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-21">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 12 additions & 3 deletions auth_oidc/tests/test_auth_oidc_auth_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def setUp(self):
super().setUp()
# search our test provider and bind the demo user to it
self.provider_rec = self.env["auth.oauth.provider"].search(
[("client_id", "=", "auth_oidc-test")]
[("name", "=", "keycloak:8080 on localhost")]
)
self.assertEqual(len(self.provider_rec), 1)

Expand All @@ -83,8 +83,10 @@ def test_auth_link(self):
).write(dict(enabled=False))
with MockRequest(self.env):
providers = OpenIDLogin().list_providers()
self.assertEqual(len(providers), 1)
auth_link = providers[0]["auth_link"]
self.assertEqual(len(providers), 2)
auth_link = list(
filter(lambda p: p["name"] == "keycloak:8080 on localhost", providers)
)[0]["auth_link"]
assert auth_link.startswith(self.provider_rec.auth_endpoint)
params = parse_qs(urlparse(auth_link).query)
self.assertEqual(params["response_type"], ["code"])
Expand All @@ -95,6 +97,13 @@ def test_auth_link(self):
self.assertTrue(params["nonce"])
self.assertTrue(params["state"])
self.assertEqual(params["redirect_uri"], [BASE_URL + "/auth_oauth/signin"])
self.assertFalse("prompt" in params)

auth_link_ms = list(
filter(lambda p: p["name"] == "Azure AD Multitenant", providers)
)[0]["auth_link"]
params = parse_qs(urlparse(auth_link_ms).query)
self.assertEqual(params["prompt"], ["select_account"])

def _prepare_login_test_user(self):
user = self.env.ref("base.user_demo")
Expand Down
3 changes: 3 additions & 0 deletions auth_oidc/views/auth_oauth_provider.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
<field name="token_endpoint" />
<field name="jwks_uri" />
</field>
<field name="auth_endpoint" position="after">
<field name="auth_link_params" />
</field>
</field>
</record>
</odoo>
Loading