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

Enhance of Azure Authentication #7022

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Enhance of Azure Authentication #7022

wants to merge 1 commit into from

Conversation

rrg92
Copy link
Contributor

@rrg92 rrg92 commented Feb 27, 2024

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.

sequenceDiagram

    User->>WikiJs:login
    WikiJs->>Microsoft: /authorize
    Microsoft->>User: /login form

    User->>Microsoft: enter credentials

    Microsoft->>WikiJs: POST redirectUrl (tokens, cookies, etc.) 

    WikiJs->>User: home page

Loading

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.

sequenceDiagram

    
    User-->>WikiJs:logoff
    User->>WikiJs: new login
    WikiJs->>Microsoft: /authorize 
    Microsoft->>Microsoft: already logged!
    Microsoft->>WikiJs: script: POST redirectUrl(tokens, cookies BLOCKED by browser) 

    WikiJs->>WikiJs: Validation fail due missing http session (due blocked cookies)
   

    WikiJs->>User: ERROR invalid username

Loading

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.

sequenceDiagram

    User->>WikiJs:login
    WikiJs->>Microsoft: /authorize
    Microsoft->>User: /login form

    User->>Microsoft: enter credentials

    Microsoft->>WikiJs: redirectUrl?DATA_QUERY_STRING

    WikiJs->>Microsoft: /token
    Microsoft->>WikiJs: redirectUrl?ACCESS_TOKEN

    WikiJs->>User: home page

    User-->>WikiJs:logoff
    User->>WikiJs: new login
    WikiJs->>Microsoft: /authorize 
    Microsoft->>Microsoft: already logged!
    Microsoft->>WikiJs: redirectUrl?DATA_QUERY_STRING 
    WikiJs->>Microsoft: /token
    Microsoft->>WikiJs: redirectUrl?ACCESS_TOKEN
    WikiJs->>User: home page

Loading

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:

@cescarsega
Copy link

Hi this is really old, any chance someone can commit this so that I can install to my instance? Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants