diff --git a/README.md b/README.md index ff8031c3..35cc766c 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ module.exports = ({env}) => ({ AZUREAD_OAUTH_CLIENT_ID: '[Client ID created in AzureAD]', // [Application (client) ID] AZUREAD_OAUTH_CLIENT_SECRET: '[Client Secret created in AzureAD]', AZUREAD_SCOPE: 'user.read', // https://learn.microsoft.com/en-us/graph/permissions-reference + AZUREAD_OAUTH_USE_OIDC: 'true', // } } }) diff --git a/admin/src/utils/axiosInstance.js b/admin/src/axiosInstance.js similarity index 100% rename from admin/src/utils/axiosInstance.js rename to admin/src/axiosInstance.js diff --git a/admin/src/utils/getTrad.js b/admin/src/getTrad.js similarity index 65% rename from admin/src/utils/getTrad.js rename to admin/src/getTrad.js index a2b8632a..3adedea8 100644 --- a/admin/src/utils/getTrad.js +++ b/admin/src/getTrad.js @@ -1,4 +1,4 @@ -import pluginId from '../pluginId'; +import pluginId from './pluginId'; const getTrad = id => `${pluginId}.${id}`; diff --git a/admin/src/pages/HomePage/index.js b/admin/src/pages/HomePage/index.js index 2ce6babb..e76d14b5 100644 --- a/admin/src/pages/HomePage/index.js +++ b/admin/src/pages/HomePage/index.js @@ -1,4 +1,4 @@ -import React, {memo, useEffect, useState} from 'react'; +import React, { memo, useEffect, useState } from 'react'; import { Alert, Button, @@ -13,12 +13,12 @@ import { Td, Th } from '@strapi/design-system'; -import {CheckPermissions} from '@strapi/helper-plugin'; -import {useIntl} from 'react-intl'; -import {Helmet} from 'react-helmet'; -import axios from '../../utils/axiosInstance' +import { CheckPermissions } from '@strapi/helper-plugin'; +import { useIntl } from 'react-intl'; +import { Helmet } from 'react-helmet'; +import axios from '../../axiosInstance' import styled from 'styled-components' -import getTrad from "../../utils/getTrad"; +import getTrad from "../../getTrad"; const ButtonWrapper = styled.div` margin: 10px 0 0 0; @@ -42,7 +42,7 @@ const AlertMessage = styled.div` ` const HomePage = () => { - const {formatMessage} = useIntl(); + const { formatMessage } = useIntl(); const [ssoRoles, setSSORoles] = useState([]) const [roles, setRoles] = useState([]) const [showSuccess, setSuccess] = useState(false) @@ -93,8 +93,8 @@ const HomePage = () => { } return ( - - + + { {/* Not required, but if it doesn't exist, it's an error. */} - + { roles.map(role => ( diff --git a/docs/en/azuread/setup.md b/docs/en/azuread/setup.md index 1ceb3806..035a620c 100644 --- a/docs/en/azuread/setup.md +++ b/docs/en/azuread/setup.md @@ -17,6 +17,7 @@ This document provides instructions for integrating AzureAD as a Single Sign-On | AZUREAD_TENANT_ID | ✅ | - | | AZUREAD_OAUTH_REDIRECT_URI | - | http://localhost:1337/strapi-plugin-sso/azuread/callback | | AZUREAD_SCOPE | - | user.read | +| AZUREAD_OAUTH_USE_OIDC | - | true | ### Configuring environment variables @@ -27,5 +28,6 @@ Use the following environment variables to configure the AzureAD integration: 3. `AZUREAD_TENANT_ID`: The Tenant ID created in AzureAD. 4. `AZUREAD_OAUTH_REDIRECT_URI`: The callback URL used by AzureAD to redirect the user after authentication. Defaults to 'http://localhost:1337/strapi-plugin-sso/azuread/callback'. 5. `AZUREAD_SCOPE`: The permissions your application requires from the user. Defaults to 'user.read'. More information on permissions can be found in the [Microsoft Graph permissions reference](https://docs.microsoft.com/en-us/graph/permissions-reference). +6. `AZUREAD_OAUTH_USE_OIDC`: Using OIDC calls graph.microsoft.com/oidc/userinfo while setting it to false calls /me as documented here : https://learn.microsoft.com/en-us/graph/api/user-get?view=graph-rest-1.0&tabs=http Make sure to replace the placeholders with the actual values you obtained from AzureAD. diff --git a/server/config/index.js b/server/config/index.js index cfeb8ab3..2adc58e5 100644 --- a/server/config/index.js +++ b/server/config/index.js @@ -14,6 +14,7 @@ module.exports = { AZUREAD_OAUTH_CLIENT_ID: '', AZUREAD_OAUTH_CLIENT_SECRET: '', AZUREAD_SCOPE: 'user.read', + AZUREAD_OAUTH_USE_OIDC: 'true', }, validator() { }, diff --git a/server/controllers/azuread.js b/server/controllers/azuread.js index fff199dd..ece9089c 100644 --- a/server/controllers/azuread.js +++ b/server/controllers/azuread.js @@ -52,6 +52,7 @@ async function azureAdSignInCallback(ctx) { const userService = getService("user"); const oauthService = strapi.plugin("strapi-plugin-sso").service("oauth"); const roleService = strapi.plugin("strapi-plugin-sso").service("role"); + const isOIDC = config["AZUREAD_OAUTH_USE_OIDC"] !== 'false'; if (!ctx.query.code) { return ctx.send(oauthService.renderSignUpError(`code Not Found`)); @@ -74,12 +75,20 @@ async function azureAdSignInCallback(ctx) { "Content-Type": "application/x-www-form-urlencoded", }, }); - const userResponse = await axios.get(OAUTH_USER_INFO_ENDPOINT, { + const apiResponse = await axios.get(isOIDC ? OAUTH_USER_INFO_ENDPOINT : 'https://graph.microsoft.com/v1.0/me', { headers: { Authorization: `Bearer ${response.data.access_token}`, }, }); + const userResponse = isOIDC ? apiResponse : { + data: { + email: apiResponse.data.userPrincipalName, + family_name: apiResponse.data.surname, + given_name: apiResponse.data.givenName, + } + } + const dbUser = await userService.findOneByEmail(userResponse.data.email); let activateUser; let jwtToken; @@ -92,8 +101,8 @@ async function azureAdSignInCallback(ctx) { const roles = azureAdRoles && azureAdRoles["roles"] ? azureAdRoles["roles"].map((role) => ({ - id: role, - })) + id: role, + })) : []; const defaultLocale = oauthService.localeFindByHeader(