Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/docs.links.check.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@
},
{
"pattern": "^https://stackoverflow.com/"
},
{
"pattern": "^https://www.jumio.com/"
},
{
"pattern": "^https://gitee.com/oauth/"
},
{
"pattern": "^https://gitlab.com/-/profile/"
}
]
}
12 changes: 6 additions & 6 deletions docs/basic/public-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,9 @@ Create a key pair on the user’s account settings page.

**Query parameters:**

```shell
/page?accessKey=<The user's access key>&accessSecret=<the user's access secret>"
```
```shell
/page?accessKey=<The user's access key>&accessSecret=<the user's access secret>"
```

Example: `https://door.casdoor.com/api/get-global-providers?accessKey=...&accessSecret=...`

Expand All @@ -211,9 +211,9 @@ Username format: `<organization>/<username>`. API calls run as that user.

**Query parameters:**

```shell
/page?username=<The user's organization name>/<The user name>&password=<the user's password>"
```
```shell
/page?username=<The user's organization name>/<The user name>&password=<the user's password>"
```

## SSO logout

Expand Down
5 changes: 3 additions & 2 deletions docs/basic/server-installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,9 @@ To use a different port, set `httpport` in `conf/app.conf` and restart the backe
:::

:::info Ports and URLs
- **Dev:** Frontend runs on port 7001 (`yarn start`). Point apps at **http://localhost:7001** for the Casdoor login page.
- **Prod:** Frontend is built and served by the backend on port 8000. Use **https://your-casdoor-domain** (or your reverse proxy URL).

- **Dev:** Frontend runs on port 7001 (`yarn start`). Point apps at `http://localhost:7001` for the Casdoor login page.
- **Prod:** Frontend is built and served by the backend on port 8000. Use `https://your-casdoor-domain` (or your reverse proxy URL).
:::

**Example:** [Casnode](https://casnode.org) uses Casdoor. In dev, set `serverUrl` to `http://localhost:7001`; in prod, set it to `https://door.casdoor.com`.
Expand Down
1 change: 0 additions & 1 deletion docs/how-to-connect/mobile-sdks/react-native-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ After sign-in, the user profile is shown.
|:-------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|
| <img src="/img/how-to-connect/mobile-sdks/react-native-app/iOS-userInfo.png" alt="iOS-userInfo" width="250" /> | <img src="/img/how-to-connect/mobile-sdks/react-native-app/Android-userInfo.png" alt="Android-userInfo" width="250" /> |


| **iOS** | **Android** |
|:--------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|
| <img src="https://github.com/casdoor/casdoor-react-native-example/blob/master/iOS-gif.gif?raw=true" alt="iOS-gif" width="250" /> | <img src="https://github.com/casdoor/casdoor-react-native-example/blob/master/Android-gif.gif?raw=true" alt="Android-gif" width="250" /> |
Expand Down
2 changes: 1 addition & 1 deletion docs/how-to-connect/oauth.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Authorization code is enabled by default for security. Enable other grant types

![Grant Types](/img/how-to-connect/oauth/accesstoken_grant_types.png)

### Authorization code grant <span id="1"></span>
### Authorization code grant

Redirect the user to:

Expand Down
1 change: 1 addition & 0 deletions docs/how-to-connect/saml/tencent-cloud.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ This guide configures Casdoor as a SAML identity provider for **Tencent Cloud**

:::info
Replace placeholders using:

- **{'{'}AccountID{'}'}**: Tencent Cloud account ID — [Account Information](https://console.cloud.tencent.com/developer)
- **{'{'}RoleName{'}'}**: Role name — [Roles](https://console.cloud.tencent.com/cam/role)
- **{'{'}ProviderName{'}'}**: SAML identity provider name — [Identity Providers](https://console.cloud.tencent.com/cam/idp)
Expand Down
191 changes: 191 additions & 0 deletions docs/integration/python/casbin-fastapi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
---
title: FastAPI
description: Using Casdoor OAuth2 authentication and Casbin authorization in a FastAPI project via casbin-fastapi-decorator.
keywords: [FastAPI, Casbin, Python, authorization, OAuth2]
authors: [Neko1313]
---

[casbin-fastapi-decorator](https://github.com/Neko1313/casbin-fastapi-decorator) is a community library that provides decorator-based Casbin authorization for FastAPI. Its **Casdoor extra** (`casbin-fastapi-decorator-casdoor`) combines Casdoor OAuth2 login with Casbin policy enforcement through Casdoor's remote enforce API, while keeping route signatures clean and dependency-injection free.

## Step 1: Deploy Casdoor

Deploy Casdoor in **production mode**. See [Server installation](/docs/basic/server-installation). Make sure the server is reachable and you can sign in (e.g. `admin` / `123`).

## Step 2: Configure a Casdoor application

In the Casdoor admin panel, create or open an application and configure:

- **Redirect URL** — add your FastAPI callback URL, e.g. `http://localhost:8080/callback`
- Copy the **Client ID**, **Client Secret**, and **Certificate**

You will also need either an **Enforcer**, **Permission**, or **Model** identifier to pass as the enforce target.

The application should start sign-in at `GET /login`; Casdoor itself should redirect back only to `GET /callback`.

## Step 3: Install the library

```bash
pip install "casbin-fastapi-decorator[casdoor]>=0.2.3"
```

Requires Python ≥ 3.10.

:::info Version guidance
Use `casbin-fastapi-decorator` `0.2.3` or newer in production. Versions `0.2.2` and earlier accepted the OAuth2 `state` parameter on the callback but did not validate it, which left the login flow without CSRF protection. Version `0.2.3` adds a dedicated `GET /login` entry point, default `CookieStateManager`, and callback `state` verification.
:::

## Step 4: Quick start with `CasdoorIntegration`

`CasdoorIntegration` is a facade that wires together the Casdoor SDK, user provider, enforcer provider, and OAuth2 router in a single call.

```python
from casbin_fastapi_decorator_casdoor import (
CasdoorEnforceTarget,
CasdoorIntegration,
)
from fastapi import FastAPI

app = FastAPI()

casdoor = CasdoorIntegration(
endpoint="http://localhost:8000",
client_id="<client-id>",
client_secret="<client-secret>",
certificate="-----BEGIN CERTIFICATE-----\n...",
org_name="built-in",
application_name="app-built-in",
target=CasdoorEnforceTarget(
enforce_id=lambda parsed: f"{parsed['owner']}/my-enforcer"
),
)

# Register GET /login, GET /callback and POST /logout routes
app.include_router(casdoor.router)

# Create a pre-configured PermissionGuard
guard = casdoor.create_guard()

@app.get("/protected")
@guard.require_permission("resource", "read")
async def protected():
return {"ok": True}

@app.get("/me")
@guard.auth_required()
async def me():
return {"ok": True}
```

Start the browser flow at `GET /login`. The router issues a one-time OAuth2 `state`, redirects to Casdoor, validates that `state` on the callback, exchanges the authorization code for tokens, and finally stores `access_token` and `refresh_token` cookies.

:::tip Custom state storage
`0.2.3` uses `CookieStateManager` by default, which is sufficient for most deployments. If you need server-side or shared state storage, pass a custom `state_manager` implementing `CasdoorStateManager`.

```python
from casbin_fastapi_decorator_casdoor import (
CasdoorStateManager,
CookieStateManager,
make_casdoor_router,
)

state_manager: CasdoorStateManager = CookieStateManager(
cookie_name="casdoor_oauth_state",
cookie_secure=True,
)

# assuming existing_sdk = AsyncCasdoorSDK(...)
router = make_casdoor_router(
sdk=existing_sdk,
state_manager=state_manager,
)
```

If you are upgrading from `0.2.2` or earlier, update your sign-in links to point at `/login` instead of constructing the Casdoor authorization URL manually.
:::

## Step 5: Choose an enforce target

`CasdoorEnforceTarget` controls which Casdoor API identifier is used for policy checks. Fields accept static strings or callables that receive the parsed JWT payload:

| Field | Casdoor API parameter |
|---|---|
| `enforce_id` | Enforcer ID |
| `permission_id` | Permission ID |
| `model_id` | Model ID |
| `resource_id` | Resource ID |
| `owner` | Organization owner |

```python
# Dynamic — organisation taken from the user's JWT
CasdoorEnforceTarget(enforce_id=lambda parsed: f"{parsed['owner']}/my-enforcer")

# Static
CasdoorEnforceTarget(permission_id="built-in/can-read-articles")
```

## Advanced usage (manual composition)

For cases requiring a custom user factory, per-route enforce targets, custom `state` storage, or custom error handling, the components can be composed directly:

```python
from casdoor import AsyncCasdoorSDK
from fastapi import FastAPI, HTTPException
from casbin_fastapi_decorator import PermissionGuard
from casbin_fastapi_decorator_casdoor import (
CasdoorEnforceTarget,
CasdoorEnforcerProvider,
CasdoorUserProvider,
CookieStateManager,
make_casdoor_router,
)

sdk = AsyncCasdoorSDK(
endpoint="http://localhost:8000",
client_id="<client-id>",
client_secret="<client-secret>",
certificate="<certificate>",
org_name="built-in",
application_name="app-built-in",
)

target = CasdoorEnforceTarget(permission_id="built-in/can-read")
user_provider = CasdoorUserProvider(sdk=sdk)
enforcer_provider = CasdoorEnforcerProvider(sdk=sdk, target=target)
router = make_casdoor_router(
sdk=sdk,
state_manager=CookieStateManager(cookie_secure=True),
redirect_after_login="/dashboard",
)

guard = PermissionGuard(
user_provider=user_provider,
enforcer_provider=enforcer_provider,
error_factory=lambda user, *rv: HTTPException(403, "Forbidden"),
)

app = FastAPI()
app.include_router(router)

@app.get("/articles")
@guard.require_permission("articles", "read")
async def list_articles():
return []
```

## Components overview

| Component | Description |
|---|---|
| `CasdoorUserProvider` | Validates `access_token` and `refresh_token` cookies via the Casdoor SDK (JWT verification) |
| `CasdoorEnforcerProvider` | Delegates policy checks to Casdoor's remote enforce API (`/api/enforce`) |
| `CasdoorEnforceTarget` | Selects which Casdoor API identifier to use; values can be static or callables receiving the parsed JWT |
| `CookieStateManager` | Default one-time OAuth2 `state` storage and verification using an HttpOnly cookie |
| `CasdoorIntegration` | Facade combining all of the above with configurable cookie, redirect, and `state` settings |
| `make_casdoor_router` | Creates an `APIRouter` with `GET /login`, `GET /callback`, and `POST /logout` |

## More resources

- [casbin-fastapi-decorator on GitHub](https://github.com/Neko1313/casbin-fastapi-decorator)
- [casbin-fastapi-decorator on PyPI](https://pypi.org/project/casbin-fastapi-decorator/)
- [casbin-fastapi-decorator-casdoor on PyPI](https://pypi.org/project/casbin-fastapi-decorator-casdoor/)
- [casbin-fastapi-decorator changelog](https://github.com/Neko1313/casbin-fastapi-decorator/blob/main/CHANGELOG.md)
1 change: 1 addition & 0 deletions docs/provider/idv/jumio.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ In the Jumio dashboard, open the API credentials section. Note your **API Token*
### 2. Create the provider in Casdoor

**Providers** → **Add**. Set **Category** to **ID Verification**, **Type** to **Jumio**, and fill in:

- **Client ID** — Jumio API Token
- **Client Secret** — Jumio API Secret
- **Endpoint** — Jumio API URL
Expand Down
2 changes: 2 additions & 0 deletions docs/provider/oauth/azureAD.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ keywords: [Azure AD, Azure, OAuth]
authors: [leo220yuyaodog]
---

<!-- markdownlint-disable MD029 -->

**Azure Active Directory (Azure AD)** provides a single identity for cloud and on-premises apps. Use it as an OAuth provider in Casdoor so users can sign in with their Microsoft accounts.

## Register an application
Expand Down
4 changes: 4 additions & 0 deletions docs/provider/oauth/baidu.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ keywords: [Baidu, Baidu OAuth]
authors: [Steve0x2a]
---

<!-- markdownlint-disable MD029 -->

1. Read [Baidu Open Auth](https://openauth.baidu.com/doc/regdevelopers.html?qq-pf-to=pcqq.c2c) and [create an application](http://developer.baidu.com/console#app/create).

![Create Baidu APP](/img/providers/OAuth/baiduapp.png)
Expand All @@ -15,6 +17,7 @@ authors: [Steve0x2a]
![Redirect URL Setting](/img/providers/OAuth/baidudomain.png)

:::caution

- Use the **domain** setting for your Casdoor domain; adding the full callback URL in the callback URL field often fails validation and breaks login.
- Only one URL or domain can be added.
:::
Expand All @@ -28,6 +31,7 @@ authors: [Steve0x2a]
![Baidu Provider](/img/providers/OAuth/baiduprovider.png)

:::info Troubleshooting

- If Baidu reports an incorrect redirect URL: add your domain in the correct place, then reset the Secret (Baidu may show an error but the secret updates after refresh). If it still fails, delete the app and create a new one, and set the domain first.
- Baidu returns a masked username; Casdoor uses that masked value as the username.
:::
2 changes: 2 additions & 0 deletions docs/provider/oauth/gitee.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ keywords: [Gitee, OAuth]
authors: [ErikQQY]
---

<!-- markdownlint-disable MD029 -->

1. Go to [Gitee OAuth applications](https://gitee.com/oauth/applications) and create an application (or open an existing one).

![Gitee Workbench](/img/providers/OAuth/giteebench.png)
Expand Down
2 changes: 2 additions & 0 deletions docs/provider/oauth/github.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ GitHub OAuth supports both the web application flow and the device flow. Use a *

## Register a GitHub App

<!-- markdownlint-disable MD029 -->

1. Go to [GitHub Developer Settings](https://github.com/settings/apps/new) and create a new **GitHub App**.
2. Set **GitHub App name**, **Homepage URL**, **Description**, and **Callback URL**.

Expand Down
2 changes: 2 additions & 0 deletions docs/provider/oauth/gitlab.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Use the [GitLab Applications](https://gitlab.com/-/profile/applications) page (o

## Create the GitLab application

<!-- markdownlint-disable MD029 -->

1. Click **Add new application**.
2. Set **Name** (e.g. "Casdoor"), **Redirect URI**, and **Scopes**.

Expand Down
2 changes: 2 additions & 0 deletions docs/provider/oauth/google.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Configure Google OAuth in the [Google API Console](https://console.developers.go

## Configure in Google Cloud

<!-- markdownlint-disable MD029 -->

1. Create or select a project. Open **APIs & Services** → **OAuth consent screen** and configure the consent screen.
2. Go to **Credentials** → **Create credentials** → **OAuth client ID**. Choose application type (e.g. Web application) and set **Authorized redirect URIs**.

Expand Down
2 changes: 2 additions & 0 deletions docs/provider/oauth/infoflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ keywords: [Infoflow, OAuth, Baidu]
authors: [Steve0x2a]
---

<!-- markdownlint-disable MD029 -->

1. Log in at [Infoflow](http://id.qy.baidu.com/static/ge/login.html#/) and open [Infoflow applications](http://qy.baidu.com/index.html#applist).
2. Register an application and note the **AgentID**.
3. In the **Setting** tab, create a management group. In address book permissions, add your structure and grant the app the needed permissions; add the app to the specified location. Add the required sensitive interface permissions.
Expand Down
2 changes: 2 additions & 0 deletions docs/provider/oauth/linkedin.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ keywords: [LinkedIn, OAuth]
authors: [ErikQQY]
---

<!-- markdownlint-disable MD029 -->

1. Create an app at [LinkedIn Developers](https://www.linkedin.com/developers/apps/new).

![LinkedIn](/img/providers/OAuth/linkedin.png)
Expand Down
1 change: 1 addition & 0 deletions docs/provider/oauth/weCom.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ WeCom supports OAuth so users can sign in from the WeCom client. You can use **i
| Agent ID | Application **AgentId** |

:::info

- **Silent:** User clicks the link and is redirected to `redirect_URI?code=CODE&state=STATE`.
- **Normal:** A consent page is shown; after the user authorizes, redirect to `redirect_uri?code=CODE&state=STATE`.

Expand Down
1 change: 1 addition & 0 deletions docs/provider/web3/metamask.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Users can sign in with MetaMask. Demo:
<video src="/video/provider/web3/login_with_metamask.mp4" controls="controls" width="100%"></video>

:::tip

- Authorize only one Ethereum address per user; Casdoor binds one address per account.
- To use a different address, disconnect the current one in Casdoor first, then sign in again with the new address.

Expand Down
1 change: 1 addition & 0 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,7 @@ module.exports = {
link: {type: "generated-index"},
items: [
"integration/python/JumpServer",
"integration/python/casbin-fastapi",
],
},
],
Expand Down
Loading
Loading