Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This Pull Request introduces new features to the Azure Authentication module in Wiki.js, enabling administrators to configure the Authorization Code Flow for authentication. This enhancement provides a more secure and robust alternative to the existing implicit flow, addressing current challenges and aligning with best practices in web security and authentication.
About current problem
The current implementation of the Azure authentication module in Wiki.js utilizes the OIDCStrategy from the passport-azure-ad library to employ an implicit flow. This configuration involves setting the response type parameter to "id_token," prompting the Azure authentication server to generate a token that fulfills Wiki.js's requirements. However, this approach mandates the use of "form_post" as the sole acceptable response format, leading the Azure server to submit a form via POST to the specified redirect URL. This method can encounter issues with browser cookie policies, particularly with the blocking of third-party cookies, which may affect the authentication process.
When a user attempts to authenticate with Azure for the first time in Wiki.js and is not already logged into Azure, they are redirected to the Microsoft login page via the /authorize endpoint. During this redirection, Wiki.js, through the passport-azure-ad module, issues a cookie intended to maintain an Express HTTP session, which stores essential validation data. Upon entering their credentials on the Microsoft login page, if the credentials are verified as correct, the user is redirected back to the configured redirect URL. At this juncture, the cookies, including the one crucial for reconstructing the previously established HTTP session, are transmitted back to Wiki.js. The passport-azure-ad module within Wiki.js then proceeds to validate all necessary elements, such as the nonce and state of the session, by cross-referencing the information retrieved from the HTTP session with the data received from Microsoft's redirection back to Wiki.js's redirect URL.
The process generally functions well until a user logs off from Wiki.js without logging off from Microsoft, a common scenario. In such cases, upon attempting to log back into Wiki.js using Azure AD, users won't encounter the usual login form from Microsoft due to their active session. Instead, because the response mode is set to "form_post" and the user is already logged in, Azure AD employs a workaround by generating a blank page that auto-submits a form via POST method. This form submission sends the authentication tokens back to the redirect URL.
However, this approach, being script-driven, can lead to browsers blocking the cookies essential for session management. Browsers may interpret these script-initiated requests as not originating directly from user interactions, akin to requests generated from an iframe, raising privacy and security concerns. This behavior is part of a broader effort by browsers to mitigate certain types of attacks and enhance user privacy, which includes stringent policies on third-party cookies. For further information on handling these browser behaviors, particularly in the context of the SameSite cookie attribute changes, refer to the Microsoft documentation: How to handle SameSite cookie changes in Chrome browser.
Furthermore, the issue is compounded by Google's initiative to phase out third-party cookies on websites, a move that is expected to impact a significant number of users. Given that Microsoft Edge is likely to adopt similar policies, the effects of this change could be widespread. For more detailed information on this development and its implications, you can visit Google's Privacy Sandbox blog which discusses the timeline and rationale behind the cookie countdown.
The solution
To address these concerns, a transition away from relying on cookies is proposed, with a move towards utilizing the Authorization Code Flow. This method involves transmitting sensitive information, such as tokens, via URL query parameters. Unlike the Implicit Flow, which directly passes the id_token, the Authorization Code Flow necessitates the inclusion of a client secret alongside the authorization code. This combination ensures secure authentication with Microsoft's services. The presence of the client secret adds a layer of security, rendering any intercepted authorization codes ineffective without it. Importantly, the client secret is only required when making requests to Azure AD, which benefits from HTTPS protection, thus ensuring the safe transmission of sensitive data through query strings even across various intermediaries like ISPs and network providers.
The primary disadvantage of transitioning to the Authorization Code Flow is the necessity for an additional request to Microsoft to retrieve the token. However, considering that Wiki.js primarily utilizes this mechanism for login validation, the impact of this extra step is likely to be minimal. This change introduces a negligible overhead in the overall authentication process, which is a small price to pay for the enhanced security and compliance benefits it brings, especially in light of evolving browser policies and the move towards more secure authentication practices.
New Option: Client Secret
To maintain compatibility with the existing version of Wiki.js, this PR introduces an option to specify a client secret within the Azure Auth module. By providing a client secret, administrators can opt for the Authorization Code Flow for authentication. If the client secret is left unspecified, the module will default to the current authentication method, which utilizes the Implicit Flow as previously described. This dual approach allows for a seamless transition and flexibility in authentication strategies, catering to various security requirements and deployment scenarios.
New Option: Issuer List
Additionally, this PR introduces the capability for users to specify a list of issuers, enhancing the module's utility in multi-tenant environments. In multi-tenant setups, it's necessary to supply identity metadata for either "/common" or "/organizations". However, the azure-passport-id library cannot autonomously discover issuer information from this metadata endpoint. By allowing the specification of an issuer list, administrators can ensure proper authentication across different tenants, improving the module's flexibility and applicability in varied organizational structures. This feature is particularly beneficial for deployments that aim to support a broad range of users from different domains or tenants within Azure AD.
New Options: Allow HTTP
The latest addition to the settings is the ability to use HTTP as the redirect URL. This feature is particularly useful for development and testing phases, allowing system administrators to test Azure authentication on their local machines without the need to put Wiki.js into debug mode. This flexibility simplifies the setup process for testing environments, ensuring that authentication workflows can be verified and debugged before being deployed in a production setting. It provides a practical tool for administrators to ensure seamless integration and functionality with Azure's authentication services in a controlled, non-production environment.
Useful Links
For a deeper understanding of the various authentication flows and their applications, the following resources are invaluable:
General Authentication Flows: Explore the different authentication scenarios and how they apply to various app types at Microsoft's Authentication Flows Overview.
Authorization Code Flow: Dive into the specifics of the Authorization Code Flow, including its secure method for authenticating users and apps, at Microsoft's Authorization Code Flow Documentation.
Implicit Flow: Learn about the Implicit Flow, its use cases, and considerations at Microsoft's Implicit Grant Flow Documentation.