Skip to content

Commit

Permalink
Rewritten README of examples/oauth2/api
Browse files Browse the repository at this point in the history
  • Loading branch information
predic8 committed Dec 19, 2024
1 parent a63aa3f commit fdfd7d6
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 22 deletions.
35 changes: 32 additions & 3 deletions distribution/examples/oauth2/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
# OAuth Examples

| Example | Description |
|------------------------------------------------------------------------|--------------------------------------|
| [API](api)| Secure API access with OAuth2 tokens |
## JWT Token Validation against Microsoft's Azure AD

See: [Tutorial](azure-ad-with-jwts/README.md)

## Securing APIs with OAuth2 and the Resource Owner Password Flow

See [Tutorial](api/README.md)

## OAuth2 authorization with OpenID-Connect and OpenID-Discovery using Membrane

Membrane API Gateway serves as authorization server.

See [Tutorial](membrane/README.md)

## OAuth2 authorization with OpenID-Connect and OpenID-Discovery using Google

Google serves as authorization server.

See [Tutorial](membrane/README.md)

## OAuth2 authorization with github as Authorization Server.

See: [Tutorial](github/README.md)

## OAuth2 authorization with google as Authorization Server.

See: [Tutorial](google/README.md)

## OAuth2 implicit Flow

See. [Tutorial](implicit/README.md)

111 changes: 107 additions & 4 deletions distribution/examples/oauth2/api/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,110 @@
# Protecting an API with OAuth2 - Resource Owner Password Flow
# Protecting an API with OAuth2 Using the Resource Owner Password Flow

This example shows the OAuth2 password flow. A client requests an access token ( with user credentials ) and the token is verified through a token validator.
This step-by-step guide demonstrates how to secure an API using OAuth2 and the Resource Owner Password Flow. A client authenticates using user credentials to request an access token, which is validated via a token validator before accessing the protected resource.

Please follow https://www.membrane-soa.org/api-gateway-doc/current/oauth2-password-flow-sample.html
The following images shows the flow of this example.
![OAuth2 Password flow for APIs](oauth2-password-flow-for-apis.png)

Alternatively a Postman based guide is available on [https://membrane-api.io/security/oauth2-using-postman/](https://membrane-api.io/security/oauth2-using-postman/)
## How to Run the Example

This example is located in the `$MEMBRANE_HOME/examples/oauth2/api` folder. Follow the instructions below to set up and test the flow:

### 1. Start the Authorization Server

In this example, Membrane acts as a pre-configured OAuth2 authorization server. You can use Membrane as-is or replace it with providers like Azure Entra ID, AWS Cognito, or Keycloak.

Steps to start the authorization server:
1. Open the `authorization_server` subfolder in a terminal.
2. Run `service-proxy.bat` or `service-proxy.sh`.
3. Verify the server is running by visiting [http://localhost:9000/admin](http://localhost:9000/admin).

### 2. Start the Server with the Protected Resource

The `token_validator` folder contains a Membrane setup that validates tokens and protects the resource.

Steps to start the token validator:
1. Open the `token_validator` folder in a terminal.
2. Run `service-proxy.bat` or `service-proxy.sh` there.
3. Verify the resource side is running at [http://localhost:9001/admin](http://localhost:9001/admin).

### 3. Get a Token and Access the Protected Resource

To request a token and access the resource, you can use a command-line client based on `curl` (detailed below). Alternatively, you can use the `rest.http` file or follow the [Postman guide](https://membrane-api.io/security/oauth2-using-postman/).

1. Open a terminal and run the client:

**Linux**:
```bash
./client.sh john password
```

**Windows**:
```cmd
client.bat john password
```

The `client.sh/bat` is requesting the token in one call to the authorization server and than calling the protected resource with the token in a second call. Both calls are displayed for illustration.

Example output:
```
1.) Requesting Token
POST http://localhost:7007/oauth2/token
grant_type=password&username=john&password=password&client_id=abc&client_secret=def
Got Token: nmsi0fsghcfq3dc9hm064eoq72
2.) Calling API
GET http://localhost:2000
Authorization: Bearer nmsi0fsghcfq3dc9hm064eoq72
Got: { "success": true }
```

**Note:** Replace `username` and `password` with appropriate credentials.



## How It Works

### Authorization Server

The authorization server authenticates users and issues access tokens.

### Token Validator

The token validator is a Membrane API Gateway instance that verifies access tokens against the authorization server. If valid, requests are forwarded to the protected resource. Invalid tokens result in a `400 Bad Request` response.

The configuration for the token validator is defined in `proxies.xml`:

```xml
<api name="Token Validator" port="2000">
<tokenValidator endpoint="http://localhost:7007/oauth2/userinfo"/>
<target host="localhost" port="3000"/>
</api>
```

- **tokenValidator**: Validates the access token.
- **target**: Routes valid requests to the protected resource.

**Important:** Ensure the resource at port 3000 is inaccessible externally in production environments to prevent unauthorized access.

### Trusted Client

The client script authenticates using user credentials to obtain an access token and calls the protected resource with the token in the `Authorization` header.

Have a look at the `client.sh/.bat` script. There you'll find some variables:

- **clientId**: Application client ID.
- **clientSecret**: Corresponding client secret.
- **tokenEndpoint**: OAuth2 token endpoint.
- **target**: Protected resource URL.

Those variables correspond with the configuration of the authentication server.

There are two script versions: Shell and PowerShell. Alternatively, a Java implementation (`OAuth2TrustedClient`) is available in the example folder.

---

## Postman Guide

Prefer using Postman? Follow the detailed guide on [Membrane API OAuth2 with Postman](https://membrane-api.io/security/oauth2-using-postman/).
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 15 additions & 15 deletions distribution/examples/oauth2/api/rest.http
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
@password =password
@clientid =abc
@clientsecret =def
@username =john

### Get access token
# @name getAADToken
POST http://localhost:7007/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=password
&username={{username}}
&password={{password}}
&client_id={{clientid}}
&client_secret={{clientsecret}}

### Extract access token from getAADToken request
@token = {{getAADToken.response.body.access_token}}
&username=john
&password=password
&client_id=abc
&client_secret=def

# Execute the POST request above. You should be a response like that:
#
# {
# "access_token": "5ta3kbi948eav3dtqs8vqus8j4",
# "token_type": "Bearer",
# "refresh_token": "6b6ll21lu7l0a8lasi9rvnstaq"
# }
#
# Copy the access_token and use it for the second request below

### Authentication using access token
### Calling the resource. using access token
GET http://localhost:2000
Authorization: Bearer {{token}}
Authorization: Bearer <<Replace me with the access_token from the response of the first call>>
7 changes: 7 additions & 0 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

# Version 6.0.0

- Update Java Version
- Change Interceptor chain from stack to instant execution
- Probably in InterceptorFlowController {
- API Key Database Filestore
- Grafana Dashboard to import in examples/prometheus
- Also provide the datasource config
- Maybe the config can be included into the docker-compose setup
- Simple JWT example
- Clean up examples in examples/oauth2

0 comments on commit fdfd7d6

Please sign in to comment.