Skip to content

lakkiy/fastapi-saml-example

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Introduction

Here is an exemplification of employing FastAPI and python3-saml libraries to implement a Service Provider (SP) functionality to facilitate Single Sign-On (SSO) integration.

Purpose of This Example

I recently needed to use FastAPI to implement SSO based on SAML, acting as a Service Provider (SP). When I checked the python3-saml library, I found that it didn’t have an example for FastAPI, but have Flask. Since I’m not very familiar with Python, having a FastAPI example would be really helpful. Then I found fastapi-saml, which was very simple and easy to understand, and it helped me a lot.

During this time, I still ran into many issues. Now, I want to share the solutions I found and my example, hoping it can help others just as fastapi-saml helped me.

What This Example Does Not Include

This example focuses specifically on implementing the login functionality within the SAML protocol. It does not include other functionalities, such as logout.

Features Included in This Example

  • Implementing a Service Provider (SP) with login functionality.
  • Generating Service Provider metadata.
  • Providing example configuration files and using MockSAML, so you don’t need to run an Identity Provider (IdP) via Docker for local development.

How to Use This Example

  1. Clone the Repository:
    git clone https://github.com/mrunhap/fastapi-saml-example && cd fastapi-saml-example
        
  2. Set Up Python Environment:
    python -m venv .venv
    source .venv/bin/activate
        
  3. Install Dependencies:
    pip install .
        
  4. Run the Application:
    uvicorn main:app --reload --port 8080
        

Navigate to http://127.0.0.1:8080/docs and test the endpoint /api/sso/saml/metadata to download the metadata file. The python3-saml library will automatically read and parse files in the saml directory, generating the required XML file. For more details, refer to the settings.

To access the SSO SAML login, visit http://127.0.0.1:8080/api/sso/saml/login. This will generate a specific URL that you need to open manually, redirecting you to the Identity Provider (IdP) login page.

After successfully logging into the IdP, it will make a request to the callback URL http://127.0.0.1:8080/api/sso/saml/callback with attributes, typically containing user information.

The callback function will use this user information to generate a JSON Web Token (JWT). The user will then be redirected to the frontend application, which will receive the token, completing the login process and granting the user access to the service.

Inside the Code: Rationale and Problem Solving

Backend Behind Nginx with HTTPS

forwarded_proto = (
    request.headers.get("X-Forwarded-Proto", "").strip() or request.url.scheme
)
rv = {
    "https": "on" if forwarded_proto == "https" else "off",

This is necessary for setups where your backend is behind Nginx and accessed through HTTPS, but Nginx communicates with your backend using HTTP. Your SP setting’s SingleSignOn URL is also HTTPS, so you might encounter the following error:

Error when processing SAML Response: invalid_response The response was received at http://your-domain.com/api/sso/saml/callback instead of https://your-domain.com/api/sso/saml/callback

To resolve this, the code checks both request.url.scheme and the X-Forwarded-Proto header in the request. Make sure to add the following to your Nginx configuration:

location / {
    proxy_pass         http://127.0.0.1:8080;
    proxy_set_header X-Forwarded-Proto $scheme;
}

CORS Error When Redirecting to IdP

return callback_url

To address the CORS errors encountered during redirection to the Identity Provider (IdP) login page, it’s better to handle this navigation differently. Instead of using a RedirectResponse, which can sometimes trigger CORS policy issues, you can return the callback URL to your client application.

By doing the redirection on the front end, you avoid the CORS issue altogether. The client can then directly navigate to the IdP login page without being affected by the same-origin policy enforced by CORS. This approach provides more control over the redirection process and minimizes potential browser security restrictions.

405 Method Not Allowed

return RedirectResponse(
    "/#/?token=" + access_token, status_code=status.HTTP_302_FOUND
)

The default value for the status_code attribute in a RedirectResponse is 307. This status code preserves the POST method during redirection, which is similar to the behavior of a callback API. However, this can cause issues if the frontend is to handle POST requests.

To avoid this issue, change the status code to 302. This will switch the redirection to use the GET method, allowing the JSON Web Token (JWT) to be correctly established and received by the frontend as intended.

Real-World SP and IdP Integration Steps

  1. Metadata Exchange: Initially, establish communication with the Identity Provider (IdP) to exchange metadata. Update the configuration settings in your SAML service (saml/settings.json) and generate a metadata XML file using the provided API. Send this XML file to the IdP. You will also receive an XML file from the IdP, which should be updated in the IdP configuration section within your local SAML configuration file.
  2. Frontend Request for SSO Login: The user initiates a request from the frontend to the /api/sso/saml/login endpoint. Upon receiving the request, the service should handle the SSO process by redirecting the browser to the URL provided in the response, which leads to the IdP login interface.
  3. User Authentication: The user completes the authentication process at the IdP. This step ensures that the user’s credentials are verified by the IdP before proceeding.
  4. IdP Callback with SAML Assertion: After successful authentication, the IdP sends a SAML assertion to the Service Provider’s callback URL (/api/sso/saml/callback) with user attributes. This assertion confirms successful authentication and includes necessary user information.
  5. JWT Token Generation and Redirection: Upon validating and processing the SAML assertion, the Service Provider’s callback function generates a JSON Web Token (JWT) for session management. The function then redirects the user back to the frontend application.
  6. Frontend Login Completion: The frontend application retrieves the JWT and completes the login process using this token to authenticate subsequent requests within the application.

Contributing

I have only scratched the surface in understanding and implementing SAML with FastAPI. If you encounter any issues or have suggestions for improvement, please feel free to open an issue or submit a pull request. Your contributions are greatly appreciated!

About

Getting FastAPI to work with SAML2

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published