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/local.mdx
+77-63Lines changed: 77 additions & 63 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,25 +11,33 @@ redirect_from:
11
11
- /identityserver/v7/bff/apis/local/
12
12
---
13
13
14
-
A _Local API_ is an API that is located within the BFF host. Local APIs are implemented with the familiar ASP.NET abstractions of API controllers or Minimal API endpoints.
A _Local API_ is an API located within the BFF host. Local APIs are implemented with the familiar ASP.NET abstractions of API controllers or Minimal API endpoints.
15
17
16
18
There are two styles of local APIs:
19
+
17
20
- Self-contained Local APIs
18
21
- Local APIs that Make Requests using Managed Access Tokens
19
22
20
23
#### Self-Contained Local APIs
24
+
21
25
These APIs reside within the BFF and don't make HTTP requests to other APIs. They access data controlled by the BFF itself, which can simplify the architecture of the system by reducing the number of APIs that must be deployed and managed. They are suitable for scenarios where the BFF is the sole consumer of the data. If you require data accessibility from other applications or services, this approach is probably not suitable.
22
26
23
27
#### Local APIs That Make Requests Using Managed Access Tokens
24
-
Alternatively, you can make the data available as a service and make HTTP requests to that service from your BFF's local endpoints. The benefits of this style of Local Endpoint include
28
+
29
+
Alternatively, you can make the data available as a service and make HTTP requests to that service from your BFF's local endpoints. The benefits of this style of Local Endpoint include:
30
+
25
31
- Your frontend's network access can be simplified into an aggregated call for the specific data that it needs, which reduces the amount of data that must be sent to the client.
26
-
- Your BFF endpoint can expose a subset of your remote APIs so that they are called in a more controlled manner than if the BFF proxied all requests to the endpoint.
32
+
- Your BFF endpoint can expose a subset of your remote APIs so that they are called in a more controlled manner than if the BFF proxied all requests to the endpoint.
27
33
- Your BFF endpoint can include business logic to call the appropriate endpoints, which simplifies your front end code.
28
34
29
-
Your local endpoints can leverage services like the HTTP client factory and Duende.BFF [token management](/bff/fundamentals/tokens) to make the outgoing calls. The following is a simplified example showing how local endpoints can obtain managed access tokens and use them to make requests to remote APIs.
35
+
Your local endpoints can leverage services like the HTTP client factory and Duende.BFF [token management](/bff/fundamentals/tokens) to make the outgoing calls.
30
36
37
+
The following is a simplified example showing how local endpoints can get managed access tokens and use them to make requests to remote APIs.
31
38
32
-
```cs
39
+
```csharp
40
+
// MyApiController.cs
33
41
[Route("myApi")]
34
42
publicclassMyApiController : ControllerBase
35
43
{
@@ -39,12 +47,12 @@ public class MyApiController : ControllerBase
39
47
{
40
48
_httpClientFactory=httpClientFactory;
41
49
}
42
-
50
+
43
51
publicasyncTask<IActionResult> Get(stringid)
44
52
{
45
53
// create HTTP client
46
54
varclient=_httpClientFactory.CreateClient();
47
-
55
+
48
56
// get current user access token and set it on HttpClient
@@ -61,84 +69,97 @@ public class MyApiController : ControllerBase
61
69
The example above is simplified to demonstrate the way that you might obtain a token. Real local endpoints will typically enforce constraints on the way the API is called, aggregate multiple calls, or perform other business logic. Local endpoints that merely forward requests from the frontend to the remote API may not be needed at all. Instead, you could proxy the requests through the BFF using either the [simple http forwarder](/bff/fundamentals/apis/remote/) or [YARP](/bff/fundamentals/apis/yarp/).
62
70
63
71
## Securing Local API Endpoints
64
-
Regardless of the style of data access used by a local API, it must be protected against threats such as [CSRF (Cross-Site Request Forgery)](https://developer.mozilla.org/en-US/docs/Glossary/CSRF) attacks. To defend against such attacks and ensure that only the frontend can access these endpoints, we recommend implementing two layers of protection.
72
+
73
+
Regardless of the style of data access used by a local API, it must be protected against threats such as [CSRF (Cross-Site Request Forgery)](https://developer.mozilla.org/en-US/docs/Glossary/CSRF) attacks. To defend against such attacks and ensure that only the frontend can access these endpoints, we recommend implementing two layers of protection.
65
74
66
75
#### SameSite Cookies
67
76
68
77
[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.
69
78
70
79
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.
71
80
72
-
73
81
#### Anti-forgery Header
74
82
75
-
For this reason, we recommend requiring an additional custom header on API endpoints, for example:
83
+
We recommend requiring an additional custom header on API endpoints, for example:
76
84
77
85
```
78
86
GET /endpoint
79
87
80
88
x-csrf: 1
81
89
```
82
90
83
-
The value of the header is not important, but its presence, combined with the cookie requirement, triggers a CORS preflight request for cross-origin calls. This effectively isolates the caller to the same origin as the backend, providing a robust security guarantee.
91
+
The value of the header is not important, but its presence, combined with the cookie requirement, triggers a CORS preflight request for cross-origin calls. This effectively isolates the caller to the same origin as the backend, providing a robust security guarantee.
84
92
85
93
Additionally, API endpoints should handle scenarios where the session has expired or authorization fails without triggering an authentication redirect to the upstream identity provider. Instead, they should return Ajax-friendly status codes.
86
94
87
95
## Setup
96
+
97
+
### Adding Anti-forgery Protection
98
+
88
99
Duende.BFF can automate the pre-processing step of requiring the custom anti-forgery header. To do so, first add the BFF middleware to the pipeline, and then decorate your endpoints to indicate that they should receive BFF pre-processing.
89
100
90
-
#### Add Middleware
91
-
Add the BFF middleware to the pipeline by calling *UseBFF*. Note that the middleware must be placed before the authorization middleware, but after routing.
101
+
<Steps>
92
102
93
-
```csharp
94
-
app.UseAuthentication();
95
-
app.UseRouting();
103
+
1.**Add Middleware to the pipeline**
96
104
97
-
app.UseBff();
105
+
Add the BFF middleware to the pipeline by calling `UseBff`. Note that the middleware must be placed before the authorization middleware, but after routing.
98
106
99
-
app.UseAuthorization();
107
+
```csharp {5}
108
+
// Program.cs
109
+
app.UseAuthentication();
110
+
app.UseRouting();
100
111
101
-
//map endpoints
102
-
```
112
+
app.UseBff();
103
113
104
-
#### Decorate Endpoints
105
-
Endpoints that require the pre- and post-processing described above must be decorated with a call to *AsBffApiEndpoint()*.
114
+
app.UseAuthorization();
106
115
107
-
For Minimal API endpoints, you can apply BFF pre- and post-processing when they are mapped.
108
-
```csharp
109
-
app.MapPost("/foo", context=> {
110
-
// ...
116
+
// map endpoints
117
+
```
118
+
119
+
2.**Decorate Endpoints**
120
+
121
+
Endpoints that require the pre- and post-processing described above must be decorated with a call to `AsBffApiEndpoint()`.
122
+
123
+
For Minimal API endpoints, you can apply BFF pre- and post-processing when they are mapped.
124
+
125
+
```csharp {4-5}
126
+
app.MapPost("/foo", context=> {
127
+
// ...
111
128
})
112
-
.RequireAuthorization() // no anonymous access
113
-
.AsBffApiEndpoint(); // BFF pre/post processing
114
-
```
129
+
.RequireAuthorization() // no anonymous access
130
+
.AsBffApiEndpoint(); // BFF pre/post processing
131
+
```
115
132
116
-
For MVC controllers, you can similarly apply BFF pre- and post-processing to controller actions when they are mapped.
117
-
```csharp
118
-
app.MapControllers()
119
-
.RequireAuthorization() // no anonymous access
120
-
.AsBffApiEndpoint(); // BFF pre/post processing
121
-
```
133
+
For MVC controllers, you can similarly apply BFF pre- and post-processing to controller actions when they are mapped.
122
134
123
-
Alternatively, you can apply the *[BffApi]* attribute directly to the controller or action.
124
-
```csharp
125
-
[Route("myApi")]
126
-
[BffApi]
127
-
publicclassMyApiController : ControllerBase
128
-
{
129
-
// ...
130
-
}
131
-
```
135
+
```csharp {2-3}
136
+
app.MapControllers()
137
+
.RequireAuthorization() // no anonymous access
138
+
.AsBffApiEndpoint(); // BFF pre/post processing
139
+
```
140
+
141
+
Alternatively, you can apply the `[BffApi]` attribute directly to the controller or action.
142
+
143
+
```csharp {2}
144
+
[Route("myApi")]
145
+
[BffApi]
146
+
publicclassMyApiController : ControllerBase
147
+
{
148
+
// ...
149
+
}
150
+
```
151
+
</Steps>
132
152
133
-
####Disabling Anti-forgery Protection
153
+
### Disabling Anti-forgery Protection
134
154
135
-
Disabling anti-forgery protection is possible but not recommended. Antiforgery protection defends against CSRF attacks, so opting out may cause security vulnerabilities.
155
+
Disabling anti-forgery protection is possible but not recommended. Antiforgery protection defends against CSRF attacks, so opting out may cause security vulnerabilities.
136
156
137
157
However, if you are defending against CSRF attacks with some other mechanism, you can opt out of Duende.BFF's CSRF protection. Depending on the version of Duende.BFF, use one of the following approaches.
138
158
139
-
For *version 1.x*, set the *requireAntiForgeryCheck* parameter to *false* when adding the endpoint. For example:
159
+
For _version 1.x_, set the `requireAntiForgeryCheck` parameter to `false` when adding the endpoint. For example:
140
160
141
-
```csharp
161
+
```csharp {6-7,14-16}
162
+
// Program.cs
142
163
// MVC controllers
143
164
app.MapControllers()
144
165
.RequireAuthorization()
@@ -148,17 +169,17 @@ app.MapControllers()
148
169
149
170
// simple endpoint
150
171
app.MapPost("/foo", context=> {
151
-
// ...
172
+
// ...
152
173
})
153
174
.RequireAuthorization()
154
175
// WARNING: Disabling antiforgery protection may make
0 commit comments