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

[Doc] Improve Access Control for Custom Pages #10357

Merged
merged 1 commit into from
Nov 19, 2024
Merged
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
55 changes: 55 additions & 0 deletions docs/CanAccess.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,59 @@ const UserEdit = () => (
| `accessDenied` | | `ReactNode` | - | The element displayed when users are denied access to the resource |
| `error` | | `ReactNode` | - | The element displayed when an error occurs while calling `authProvider.canAccess` |

## Securing Custom Routes

By default, there is no authentication or authorization control on custom routes. If you need to restrict access to a custom route, wrap the content with `<CanAccess>`. Remember to check the authentication status before with `<Authenticated>`:

```tsx
import { Authenticated, CanAccess, AccessDenied } from 'react-admin';

export const LogsPage = () => (
<Authenticated>
<CanAccess resource="logs" action="read" accessDenied={<AccessDenied />}>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The important part is the accessDenied={<AccessDenied />} part, which was missing.

...
</CanAccess>
</Authenticated>
);
```

Use the [`<CustomRoutes>`](./CustomRoutes.md) component to add custom routes to your admin.

```tsx
import { Admin, CustomRoutes, Authenticated, CanAccess, AccessDenied, Layout } from 'react-admin';
import { Route } from 'react-router-dom';

import { LogsPage } from './LogsPage';
import { MyMenu } from './MyMenu';

const MyLayout = (props) => <Layout {...props} menu={MyMenu} />;

const App = () => (
<Admin authProvider={authProvider} layout={MyLayout}>
<CustomRoutes>
<Route path="/logs" element={<LogsPage />} />
</CustomRoutes>
</Admin>
);
```

Remember to also wrap your [custom menu items](./Menu.md) with `<CanAccess>` to hide the menu items if the user doesn't have access to the resource.

```tsx
import { Menu, CanAccess } from "react-admin";
import SsidChartIcon from "@mui/icons-material/SsidChart";

export const MyMenu = () => (
<Menu>
<Menu.ResourceItems />
<CanAccess resource="logs" action="read">
<Menu.Item primaryText="Logs" to="/logs" leftIcon={<SsidChartIcon />} />
</CanAccess>
</Menu>
);
```

**Note**: You don't need to use `<CanAccess>` on the core react-admin page components (`<List>`, `<Create>`, `<Edit>`, `<Show>`) because they already have built-in access control.

**Note**: You don't need to use `<Authenticated>` on custom pages if your admin uses [`requireAuth`](./Admin.md#requireauth).

51 changes: 40 additions & 11 deletions docs/Permissions.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,30 +253,59 @@ const CommentsToolbar = ({ record }) => (

### Custom Routes

By default, there is no authentication or authorization control on the custom routes. If you need to restrict access to a custom route, you can use the `<CanAccess>` component. Remember to check the authentication status before with `<Authenticated>`:
By default, there is no authentication or authorization control on custom routes. If you need to restrict access to a custom route, you can use the `<CanAccess>` component. Remember to check the authentication status before with `<Authenticated>`:

```tsx
import { Admin, CustomRoutes, Authenticated, CanAccess } from 'react-admin';
import { Authenticated, CanAccess, AccessDenied } from 'react-admin';

export const LogsPage = () => (
<Authenticated>
<CanAccess resource="logs" action="read" accessDenied={<AccessDenied />}>
...
</CanAccess>
</Authenticated>
);
```

Use the [`<CustomRoutes>`](./CustomRoutes.md) component to add custom routes to your admin.

```tsx
import { Admin, CustomRoutes, Authenticated, CanAccess, AccessDenied, Layout } from 'react-admin';
import { Route } from 'react-router-dom';

import { LogsPage } from './LogsPage';
import { MyMenu } from './MyMenu';

const MyLayout = (props) => <Layout {...props} menu={MyMenu} />;

const App = () => (
<Admin authProvider={authProvider}>
<Admin authProvider={authProvider} layout={MyLayout}>
<CustomRoutes>
<Route path="/restricted" element={
<Authenticated>
<CanAccess action="read" resource="restricted">
<RestrictedPage />
</CanAccess>
</Authenticated>
} />
<Route path="/logs" element={<LogsPage />} />
</CustomRoutes>
</Admin>
);
```

Remember to also wrap your [custom menu items](./Menu.md) with `<CanAccess>` to hide the menu items if the user doesn't have access to the resource.

```tsx
import { Menu, CanAccess } from "react-admin";
import SsidChartIcon from "@mui/icons-material/SsidChart";

export const MyMenu = () => (
<Menu>
<Menu.ResourceItems />
<CanAccess resource="logs" action="read">
<Menu.Item primaryText="Logs" to="/logs" leftIcon={<SsidChartIcon />} />
</CanAccess>
</Menu>
);
```

**Note**: You don't need to use `<CanAccess>` on the core react-admin page components (`<List>`, `<Create>`, `<Edit>`, `<Show>`) because they already have built-in access control.

**Note**: You don't need to use `<CanAccess>` on custom pages if your admin uses [`requireAuth`](./Admin.md#requireauth).
**Note**: You don't need to use `<Authenticated>` on custom pages if your admin uses [`requireAuth`](./Admin.md#requireauth).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd move that tip below the example that uses <Authenticated>

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about that, too, but I feel that it interrupts the flow of the explanation for a particular case. So I'm -1 for this change.


## Permissions

Expand Down
Loading