You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/docs/bff/fundamentals/apis/remote.md
+28-18Lines changed: 28 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,55 +11,65 @@ redirect_from:
11
11
- /identityserver/v7/bff/apis/remote/
12
12
---
13
13
14
-
A _Remote API_ is an API that is deployed separately from the BFF host. Remote APIs use access tokens to authenticate and authorize requests, but the frontend does not possess an access token to make requests to remote APIs directly. Instead, all access to remote APIs is proxied through the BFF, which authenticates the frontend using its authentication cookie, obtains the appropriate access token, and forwards the request to the Remote API with the token attached.
14
+
A _Remote API_ is an API that is deployed separately from the BFF host. Remote APIs use access tokens to authenticate and authorize requests, but the frontend does not possess an access token to make requests to remote APIs directly. Instead, all access to remote APIs is proxied through the BFF, which authenticates the frontend using its authentication cookie, gets the appropriate access token, and forwards the request to the Remote API with the token attached.
15
15
16
-
There are two different ways to set up Remote API proxying in Duende.BFF. This page describes the built-in simple HTTP forwarder. Alternatively, you can integrate Duende.BFF with Microsoft's reverse proxy [YARP](/bff/fundamentals/apis/yarp), which allows for more complex reverse proxy features provided by YARP combined with the security and identity features of Duende.BFF.
16
+
There are two different ways to set up Remote API proxying in Duende.BFF. This page describes the built-in simple HTTP forwarder. Alternatively, you can integrate Duende.BFF with Microsoft's [YARP](/bff/fundamentals/apis/yarp) reverse proxy, which allows for more complex reverse proxy features provided by YARP combined with the security and identity features of Duende.BFF.
17
17
18
18
## Simple HTTP forwarder
19
19
20
20
Duende.BFF's simple HTTP forwarder maps routes in the BFF to a remote API surface. It uses [Microsoft YARP](https://github.com/microsoft/reverse-proxy) internally, but is much simpler to configure than YARP. The intent is to provide a developer-centric and simplified way to proxy requests from the BFF to remote APIs when more complex reverse proxy features are not needed.
21
21
22
22
These routes receive automatic anti-forgery protection and integrate with automatic token management.
23
23
24
-
To enable this feature, add a reference to the *Duende.BFF.Yarp* NuGet package, add the remote APIs service to DI, and call the *MapRemoteBFFApiEndpoint* method to create the mappings.
24
+
To enable this feature, add a reference to the *Duende.BFF.Yarp* NuGet package, add the remote APIs service to the service provider, and then add the remote endpoint mappings.
25
25
26
-
#### Add Remote API Service to DI
26
+
#### Add Remote API Service to Service Provider
27
27
28
-
```cs
28
+
To use the HTTP forwarder, register it in the service provider:
29
+
30
+
```csharp {3}
31
+
// Program.cs
29
32
builder.Services.AddBff()
30
33
.AddRemoteApis();
31
34
```
32
35
33
-
34
36
#### Map Remote APIs
35
-
Use the *MapRemoteBffApiEndpoint* extension method to describe how to map requests coming into the BFF out to remote APIs and the *RequireAccessToken* method to specify token requirements. *MapRemoteBffApiEndpoint* takes two parameters: the base path of requests that will be mapped externally, and the address to the external API where the requests will be mapped. *MapRemoteBffApiEndpoint* maps a path and all sub-paths below it. The intent is to allow easy mapping of groups of URLs. For example, you can set up mappings for the /users, /users/{userId}, /users/{userId}/books, and /users/{userId}/books/{bookId} endpoints like this:
36
37
37
-
```cs
38
+
Use the `MapRemoteBffApiEndpoint` extension method to describe how to map requests coming into the BFF to remote APIs.
39
+
40
+
`MapRemoteBffApiEndpoint` takes two parameters: the base path of requests that will be mapped externally, and the address to the external API where the requests will be mapped.
41
+
42
+
The `MapRemoteBffApiEndpoint` extension method maps a path and all sub-paths below it. The intent is to allow easy mapping of groups of URLs. For example, you can set up mappings for the `/users`, `/users/{userId}`, `/users/{userId}/books`, and `/users/{userId}/books/{bookId}` endpoints without having to explicitly include all of them:
This example opens up the complete */users* API namespace to the frontend and thus to the outside world. Try to be as specific as possible when designing the forwarding paths.
51
+
This example opens up the complete */users* API namespace to the frontend, and thus, to the outside world. While it is convenient to register API paths this way, consider if you need to be more specific hen designing the forwarding paths to prevent accidentally exposing unintended endpoints.
44
52
:::
45
53
54
+
The `RequireAccessToken` method can be added to [specify token requirements](#access-token-requirements) for the remote API. The BFF will automatically forward the correct access token to the remote API, which will be scoped to the client application, the user, or either.
55
+
46
56
## Securing Remote APIs
57
+
47
58
Remote APIs typically require access control and must be protected against threats such as [CSRF (Cross-Site Request Forgery)](https://developer.mozilla.org/en-US/docs/Glossary/CSRF) attacks.
48
59
49
60
To provide access control, you can specify authorization policies on the mapped routes, and configure them with access token requirements.
50
61
51
62
To defend against CSRF attacks, you should use SameSite cookies to authenticate calls from the frontend to the BFF. As an additional layer of defense, APIs mapped with *MapRemoteBffApiEndpoint* are automatically protected with an anti-forgery header.
52
63
53
-
54
64
#### SameSite cookies
65
+
55
66
[The SameSite cookie attribute](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value) is a feature of modern browsers that restricts cookies so that they are only sent to pages originating from the [site](https://developer.mozilla.org/en-US/docs/Glossary/Site) where the cookie was originally issued. This prevents CSRF attacks, because cross site requests will no longer implicitly include the user's credentials.
56
67
57
68
This is a good first layer of defense, but makes the assumption that you can trust all subdomains of your site. All subdomains within a registrable domain are considered the same site for purposes of SameSite cookies. Thus, if another application hosted on a subdomain within your site is infected with malware, it can make CSRF attacks against your application.
58
69
59
-
60
70
#### Anti-forgery header
61
71
62
-
For this reason, remote APIs automatically require an additional custom header on API endpoints. For example:
72
+
Remote APIs mapped in the BFF always require an additional custom header on API endpoints. For example:
63
73
64
74
```text
65
75
GET /endpoint
@@ -71,25 +81,25 @@ The value of the header is not important, but its presence, combined with the co
71
81
72
82
#### Require authorization
73
83
74
-
The *MapRemoteBffApiEndpoint* method returns the appropriate type to integrate with the ASP.NET Core authorization system. You can attach authorization policies to remote endpoints using **RequireAuthorization**, just as you would for a standard ASP.NET core endpoint created with *MapGet*, and the authorization middleware will then enforce that policy before forwarding requests on that route to the remote endpoint.
84
+
The `MapRemoteBffApiEndpoint` method returns the appropriate type to integrate with the ASP.NET Core authorization system. You can attach authorization policies to remote endpoints using `RequireAuthorization` extension method, just as you would for a standard ASP.NET core endpoint created with `MapGet`. The authorization middleware will then enforce that policy before forwarding requests on that route to the remote endpoint.
75
85
76
86
#### Access token requirements
77
87
78
-
Remote APIs sometimes allow anonymous access, but usually require an access token, and the type of access token (user or client) will vary as well. You can specify access token requirements via the **RequireAccessToken** extension method. Its **TokenType** parameter has three options:
88
+
Remote APIs sometimes allow anonymous access, but usually require an access token, and the type of access token (user or client) will vary as well. You can specify access token requirements via the `RequireAccessToken` extension method. Its `TokenType` parameter has three options:
79
89
80
-
****User***
90
+
*`User`
81
91
82
92
A valid user access token is required and will be forwarded to the remote API. A user access token is an access token obtained during an OIDC flow (or subsequent refresh), and is associated with a particular user. User tokens are obtained when the user initially logs in, and will be automatically refreshed using a refresh token when they expire.
83
93
84
-
****Client***
94
+
*`Client`
85
95
86
96
A valid client access token is required and will be forwarded to the remote API. A client access token is an access token obtained through the client credentials flow, and is associated with the client application, not any particular user. Client tokens can be obtained even if the user is not logged in.
87
97
88
-
****UserOrClient***
98
+
*`UserOrClient`
89
99
90
100
Either a valid user access token or a valid client access token (as fallback) is required and will be forwarded to the remote API.
91
101
92
-
You can also use the *WithOptionalUserAccessToken* extension method to specify that the API should be called with a user access token if one is available and anonymously if not.
102
+
You can also use the `WithOptionalUserAccessToken` extension method to specify that the API should be called with a user access token if one is available and anonymously if not.
93
103
94
104
:::note
95
105
These settings only specify the logic that is applied before the API call gets proxied. The remote APIs you are calling should always specify their own authorization and token requirements.
0 commit comments