Skip to content

Commit d53d35c

Browse files
authored
Yaml oauth2 example readme (#2561)
* refactor: update security examples to YAML, improve clarity in OAuth2 and JWT configurations - Migrated security examples from Groovy to YAML for readability and consistency. - Refined API flows and comments for `apikey-to-jwt-conversion` and OAuth2 examples. - Enhanced documentation in `README.md` with clear descriptions of API key, JWT, and OAuth2 usage. * docs: fix broken link to Prometheus and Grafana example in README.md * fix: correct indentation in OAuth2 example and typo in README
1 parent b4b296e commit d53d35c

3 files changed

Lines changed: 67 additions & 73 deletions

File tree

README.md

Lines changed: 56 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -869,80 +869,81 @@ api:
869869
870870
# Security
871871
872-
Membrane offers lots of security features to protect backend servers.
872+
Membrane offers all kinds of security features to protect APIs and backend servers.
873873
874874
## API Keys
875875
876-
You can define APIs keys directly in your configuration, and Membrane will validate incoming requests against them.
876+
API keys can be defined in the configuration, loaded from a file, or stored in a database. Requests are authenticated by validating the provided API key against these sources.
877877
878-
### Example Configuration
879-
The following configuration secures the `Fruitshop API` by validating an API key provided as a query parameter:
878+
You can also define permissions using scopes in OpenAPI and enforce them with API keys, OAuth 2.0, or JWT-based authentication.
880879
881-
```xml
882-
<api port="2000">
883-
<apiKey>
884-
<!-- Define valid API keys -->
885-
<simple>
886-
<secret value="abc123" />
887-
<secret value="secret" />
888-
<secret value="Paris2025" />
889-
</simple>
890-
891-
<!-- Extract the API key from the query parameter -->
892-
<queryParamExtractor paramName="api-key" />
893-
</apiKey>
894-
<target url="https://api.predic8.de" />
895-
</api>
896-
```
880+
This configuration secures all APIs globally. Alternatively, API keys can be defined for individual APIs only.
897881
898-
### Testing the Configuration
899-
To test the configuration, pass a valid API key in the query string:
882+
```yaml
883+
global:
884+
- apiKey:
885+
stores:
886+
- simple:
887+
- secret:
888+
value: aed8bcc4-7c83-44d5-8789-21e4024ac873
889+
- secret:
890+
value: 08f121fa-3cda-49c6-90db-1f189ff80756
891+
extractors:
892+
- headerExtractor:
893+
headerName: X-Api-Key
894+
```
900895
901-
```bash
902-
curl "http://localhost:2000/shop/v2/products/4?api-key=abc123"
903-
```
896+
### Advanced Use Cases
904897
905-
If the key is invalid or missing, Membrane denies access and returns an error response (HTTP 401 Unauthorized).
898+
More advanced scenarios are supported, including:
906899
907-
### Advanced Use Cases
908-
For more complex setups, such as API keys in the HTTP header, role-based access control (RBAC) or file-based key storage, see the [API Key Plugin Examples](./distribution/examples/security/api-key/rbac/README.md).
900+
- API keys in headers, query parameters or at any other location using expressions.
901+
- Role-based access control (RBAC) with fine-grained permissions.
902+
- OpenAPI-defined permissions.
903+
904+
See the [API Key Plugin Examples](./distribution/examples/security/api-key/rbac/README.md) for detailed configurations.
909905
910906
## JSON Web Tokens
911907
912-
The API below only allows requests with valid tokens from Microsoft's Azure AD. You can also use the JWT validator for other identity providers.
908+
The API below only allows requests that present a valid JSON Web Token issued by Microsoft Azure Entra ID. The JWT validator can also be used with other identity providers.
913909
914-
```xml
915-
<api port="8080">
916-
<jwtAuth expectedAud="api://2axxxx16-xxxx-xxxx-xxxx-faxxxxxxxxf0">
917-
<jwks jwksUris="https://login.microsoftonline.com/common/discovery/keys"/>
918-
</jwtAuth>
919-
<target url="https://your-backend"/>
920-
</api>
910+
```yaml
911+
api:
912+
port: 2000
913+
flow:
914+
- jwtAuth:
915+
expectedAud: api://2axxxx16-xxxx-xxxx-xxxx-faxxxxxxxxf0
916+
jwks:
917+
jwksUris: https://login.microsoftonline.com/common/discovery/keys
918+
target:
919+
url: https://your-backend
921920
```
922921
923922
## OAuth2
924923
925924
### Secure APIs with OAuth2
926925
927-
Use OAuth2/OpenID to secure endpoints against Google, Azure AD, GitHub, Keycloak or Membrane authentication servers.
926+
Use OAuth2/OpenID to secure endpoints against Google, Azure Entra ID, GitHub, Keycloak or Membrane Authentication Servers.
928927
929-
```xml
930-
<api port="2001">
931-
<oauth2Resource2>
932-
<membrane src="https://accounts.google.com"
933-
clientId="INSERT_CLIENT_ID"
934-
clientSecret="INSERT_CLIENT_SECRET"
935-
scope="email profile"
936-
subject="sub"/>
937-
</oauth2Resource2>
938-
<groovy>
939-
// Get email from OAuth2 and forward it to the backend
940-
def oauth2 = exc.properties.'membrane.oauth2'
941-
header.setValue('X-EMAIL',oauth2.userinfo.email)
942-
CONTINUE
943-
</groovy>
944-
<target url="https://backend"/>
945-
</api>
928+
```yaml
929+
api:
930+
port: 2000
931+
flow:
932+
- oauth2Resource2:
933+
membrane:
934+
src: http://localhost:8000
935+
clientId: abc
936+
clientSecret: def
937+
scope: openid profile
938+
claims: username
939+
claimsIdt: sub
940+
- request:
941+
# Forward the authenticated user’s email to the backend in an HTTP header.
942+
- setHeader:
943+
name: X-EMAIL
944+
value: ${property['membrane.oauth2'].userinfo['email']}
945+
target:
946+
url: http://backend
946947
```
947948
948949
Try the tutorial [OAuth2 with external OpenID Providers](https://membrane-soa.org/api-gateway-doc/current/oauth2-openid.html)
@@ -1156,7 +1157,7 @@ This API will expose metrics for Prometheus at [http://localhost:2000/metrics](h
11561157
![Grafana Dashborad for Membrane API Gateway](/docs/images/membrane-grafana-dashboard.png)
11571158
Grafana dashboard from Membrane metrics.
11581159
1159-
See [Prometheus and Grafana example](distribution/examples/monitoring-tracing/prometheus).
1160+
See [Prometheus and Grafana example](distribution/examples/monitoring-tracing/prometheus-grafana).
11601161
11611162
### OpenTelemetry Integration
11621163
Membrane supports integration with **OpenTelemetry** traces using the `openTelemetry` plugin and the `W3C` propagation standard. This enables detailed tracing of requests across Membrane and backend services.

distribution/examples/security/jwt/apikey-to-jwt-conversion/apis.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ api:
2626
jwk:
2727
location: jwk.json
2828
- return: {}
29-
3029
---
3130

3231
api:

distribution/examples/security/oauth2/membrane/client/apis.yaml

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
# yaml-language-server: $schema=https://www.membrane-api.io/v7.0.5.json
22
api:
3-
name: Resource Server
43
port: 2000
54
flow:
6-
- log: {}
75
# Protects a resource with OAuth2 - blocks on invalid login
86
- oauth2Resource2:
97
membrane:
@@ -13,29 +11,25 @@ api:
1311
scope: openid profile
1412
claims: username
1513
claimsIdt: sub
16-
# Use the information from the authentication server and pass it to the resource server (optional)
17-
- groovy:
18-
src: |
19-
def oauth2 = exc.properties.'membrane.oauth2'
20-
// Put the eMail into the header X-EMAIL and pass it to the protected server.
21-
exc.request.header.setValue('X-EMAIL',oauth2.userinfo.email)
22-
CONTINUE
14+
- request:
15+
# Forward the authenticated user’s email to the backend in an HTTP header.
16+
- setHeader:
17+
name: X-EMAIL
18+
value: ${property['membrane.oauth2'].userinfo['email']}
2319
target:
24-
host: localhost
25-
port: 3000
20+
url: http://localhost:3000
2621

2722
---
28-
2923
api:
3024
port: 3000
3125
flow:
32-
- groovy:
33-
src: |
34-
exc.setResponse(Response.ok("You accessed the protected resource! Hello " + exc.request.header.getFirstValue("X-EMAIL")).build())
35-
RETURN
26+
- request:
27+
- template:
28+
src: You accessed the protected resource! Hello ${header["X-EMAIL"]}
29+
- return:
30+
status: 200
3631

3732
---
38-
3933
api:
4034
port: 9001
4135
flow:

0 commit comments

Comments
 (0)