You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
6.4 KiB

  1. <section class="oe_container">
  2. <div class="oe_row oe_spaced">
  3. <div class="oe_span12">
  4. <h2 class="oe_slogan">Galicea OpenID Connect Provider</h2>
  5. <h3 class="oe_slogan">
  6. OpenID Connect Provider for Odoo &amp; OAuth2 resource server
  7. </h3>
  8. <p>
  9. This add-on allows Odoo to become an OpenID Connect Identity Provider (or just OAuth2 authorization server). The supported use-case is to allow several company-owned applications (possibly other Odoo instances) to reuse identities provided by Odoo, by becoming its OpenID Connect Clients. <i>There is no technical reason not to allow third-party clients, but keep in mind that as is, there is no support for custom scopes (other than <tt>openid</tt>) and no permission is required from the user to share their identity with the client.</i></p>
  10. <p>The add-on also provides OAuth2 token validation for use in custom API endpoints. This allows the clients to securely fetch data from Odoo.</p>
  11. <h2>Prerequisites</h2>
  12. <pre>
  13. pip install -r galicea_openid_connect/requirements.txt
  14. </pre>
  15. <h2>Client configuration</h2>
  16. <p>
  17. Simply go to <tt>OpenID Connect Provider</tt> menu to register a new client. Make sure that the <tt>Redirect URI</tt> exactly matches <tt>redirect_uri</tt> parameter your client is going to send. Copy generated <tt>Client ID</tt> and <tt>Client secret</tt> to configure your client.
  18. </p>
  19. <p>
  20. You can use <a href="https://openid.net/specs/openid-connect-discovery-1_0.html">OpenID Connect Discovery</a> to set up your client. The discovery document URL will be located at <tt>&lt;odoo-base-url&gt;/.well-known/openid-configuration</tt> and it looks like this: <pre>
  21. {
  22. "authorization_endpoint": "&lt;odoo-base-url&gt;/oauth/authorize",
  23. "grant_types_supported": [
  24. "authorization_code",
  25. "implicit"
  26. ],
  27. "id_token_signing_alg_values_supported": [
  28. "RS256"
  29. ],
  30. "issuer": "&lt;odoo-base-url&gt;/",
  31. "jwks_uri": "&lt;odoo-base-url&gt;/oauth/jwks",
  32. "response_types_supported": [
  33. "code",
  34. "token",
  35. "id_token token",
  36. "id_token"
  37. ],
  38. "scopes_supported": [
  39. "openid"
  40. ],
  41. "subject_types_supported": [
  42. "public"
  43. ],
  44. "token_endpoint": "&lt;odoo-base-url&gt;/oauth/token",
  45. "token_endpoint_auth_methods_supported": [
  46. "client_secret_post"
  47. ],
  48. "userinfo_endpoint": "&lt;odoo-base-url&gt;/oauth/userinfo"
  49. }
  50. </pre>
  51. <h3>Configuring other Odoo instance/DB to be the client</h3>
  52. <p>Let's say that you want to allow users registered in your <tt>master.odoo.com</tt> Odoo instance to be able to log into <tt>client.odoo.com</tt> instance, without having to create a separate account.</p>
  53. <p>To do that, simply install this module on <tt>master.odoo.com</tt> and add the client, using <tt>/auth_oauth/signin</tt> as a redirect_uri:</p>
  54. <img class="oe_picture oe_screenshot" src="images/master_screenshot.png" />
  55. <p>Now, in <tt>client.odoo.com</tt>:
  56. <ul>
  57. <li>install the <tt>auth_oauth</tt> add-on,</li>
  58. <li>enable developer mode,</li>
  59. <li>make sure that <tt>Allow external users to sign up</tt> option is enabled in <tt>General settings</tt></li>
  60. <li>add the following OAuth Provider data in the settings:</li>
  61. <img class="oe_picture oe_screenshot" src="images/client_screenshot.png" />
  62. </p>
  63. Now, the users of <tt>client.odoo.com</tt> will be able to login using new <tt>Login with Master</tt> link.
  64. <img class="oe_picture oe_screenshot" src="images/login_screenshot.png" />
  65. In case they are already logged into <tt>master.odoo.com</tt>, all they need to do is to click it. Otherwise, they will be redirected to <tt>master.odoo.com</tt> to provide their credentials.
  66. <h2>Creating JSON APIs with OAuth2 authorization</h2>
  67. <p>Along with the ID token, it's possible for the OpenID Connect Client to request access token, that can be used to authorize access to a custom JSON API.</p>
  68. <p>You can create such API in a way that is similar to creating regular Odoo controllers:</p>
  69. <pre>
  70. # -*- coding: utf-8 -*-
  71. from odoo import http
  72. from odoo.addons.galicea_openid_connect.api import resource
  73. class ExternalAPI(http.Controller):
  74. @resource('/oauth/userinfo', method='GET')
  75. def userinfo(self, req, **query):
  76. user = req.env.user
  77. return {
  78. 'sub': str(user.id),
  79. 'name': user.name,
  80. 'email': user.email
  81. }
  82. </pre>
  83. (note that this particular endpoint is bundled into <tt>galicea_openid_connect</tt> add-on). The client can then call this endpoint with either a header that looks like <tt>Authorization: Bearer &lt;token&gt;</tt> or <tt>&amp;access_token=&lt;token&gt;</tt> query parameter.
  84. <pre>
  85. $ curl --header 'Authorization: Bearer 9Dkv2W...gzpz' '&lt;odoo-base-url&gt;/oauth/userinfo'
  86. {"email": false, "sub": "1", "name": "Administrator"}
  87. </pre>
  88. <h3>API authorized with client credentials tokens</h3>
  89. It's also possible to create APIs for server-to-server requests from the Client.
  90. <pre>
  91. # -*- coding: utf-8 -*-
  92. from odoo import http
  93. from odoo.addons.galicea_openid_connect.api import resource
  94. class ExternalAPI(http.Controller):
  95. @resource('/oauth/clientinfo', method='GET'<b>, auth='client'</b>)
  96. def clientinfo(self, req, **query):
  97. client = req.env['galicea_openid_connect.client'].browse(req.context['client_id'])
  98. return {
  99. 'name': client.name
  100. }
  101. </pre>
  102. (note that this particular endpoint is bundled into <tt>galicea_openid_connect</tt> add-on as well). In order to receive the access token, the client needs to call the <tt>/oauth/token</tt> endpoint with <tt>&amp;grant_type=client_credentials</tt> parameter:
  103. <pre>
  104. $ curl -X POST '&lt;odoo-base-url&gt;/oauth/token?grant_type=client_credentials&client_id=dr...ds&client_secret=DL...gO'
  105. {"access_token": "WWy74uJIIRA4bonJHdVUeY3N8Jn2vuMecIfQntLf5FvCj3C3nNJY9tRER0qcoHRw", "token_type": "bearer"}
  106. </pre>
  107. Such token can then be used to access the resource:
  108. <pre>
  109. $ curl --header 'Authorization: Bearer WWy...coHRw' '&lt;odoo-base-url&gt;/oauth/clientinfo'
  110. {"name": "Test Client"}
  111. </pre>
  112. <h2>Additional notes</h2>
  113. <ul>
  114. <li>In order to support OpenID Connect features related to authentication time, this also adds time of the user log-in to Odoo session.</li>
  115. <li>For each client, a special kind of public user ("system user") is created to be impersonated during the server-server API requests.</li>
  116. </ul>
  117. </div>
  118. </div>
  119. </section>