-
Notifications
You must be signed in to change notification settings - Fork 0
added m2m example + readme #11
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
Merged
MaartendeKruijf
merged 12 commits into
development
from
feature/10-add-m2m-token-obtain-example
Dec 19, 2024
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
2e9a582
added m2m example + readme
RabbITCybErSeC ee4a93d
formatting fix
RabbITCybErSeC 86d59dc
formatting fix
RabbITCybErSeC 73ef141
added link to authentik
RabbITCybErSeC 9da47a7
addressed review
RabbITCybErSeC a57bfec
added build for examples
RabbITCybErSeC 527fbfb
added build to ci
RabbITCybErSeC 78c9e2d
ci version go upgrade
RabbITCybErSeC da94a1a
fixed make file according to review
ce01792
add examples build to ci
cd4953f
fixes linting issue
954daed
addressed linting issue
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,50 @@ | ||
| .PHONY: test | ||
| test: | ||
| go test ./... -v | ||
| lint: | ||
| GOFLAGS=-buildvcs=false golangci-lint run --timeout 5m0s -v | ||
| .DEFAULT_GOAL := dev | ||
|
|
||
| .PHONY: build-basic | ||
| build-basic: | ||
| cd examples/basic && go build ./... | ||
|
|
||
| .PHONY: build-validation | ||
| build-validation: | ||
| cd examples/validation && go build ./... | ||
|
|
||
| .PHONY: build-m2m | ||
| build-m2m: | ||
| cd examples/m2m && go build ./... | ||
|
|
||
| .PHONY: test-basic | ||
| test-basic: | ||
| cd examples/basic && go test ./... -v | ||
|
|
||
| .PHONY: test-validation | ||
| test-validation: | ||
| cd examples/validation && go test ./... -v | ||
|
|
||
| .PHONY: test-m2m | ||
| test-m2m: | ||
| cd examples/m2m && go test ./... -v | ||
|
|
||
| .PHONY: lint-basic | ||
| lint-basic: | ||
| cd examples/basic && GOFLAGS=-buildvcs=false golangci-lint run --timeout 5m0s -v | ||
|
|
||
| .PHONY: lint-validation | ||
| lint-validation: | ||
| cd examples/validation && GOFLAGS=-buildvcs=false golangci-lint run --timeout 5m0s -v | ||
|
|
||
| .PHONY: lint-m2m | ||
| lint-m2m: | ||
| cd examples/m2m && GOFLAGS=-buildvcs=false golangci-lint run --timeout 5m0s -v | ||
|
|
||
| .PHONY: build-examples | ||
| build-examples: build-basic build-validation build-m2m | ||
|
|
||
| .PHONY: test | ||
| test: test-basic test-validation test-m2m | ||
|
|
||
| .PHONY: lint | ||
| lint: lint-basic lint-validation lint-m2m | ||
|
|
||
| .PHONY: dev | ||
| dev: | ||
| @echo "Development target (customize as needed)" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| module example | ||
|
|
||
| go 1.23.4 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| package main | ||
|
|
||
| import ( | ||
| "crypto/tls" | ||
| "encoding/json" | ||
| "fmt" | ||
| "io" | ||
| "log" | ||
| "net/http" | ||
| "net/url" | ||
| "os" | ||
| "strconv" | ||
| "strings" | ||
| ) | ||
|
|
||
| // TokenConfig represents the configuration for token retrieval | ||
| type TokenConfig struct { | ||
| BaseURL string | ||
| ClientID string | ||
| ServiceAccount string | ||
| ServiceToken string | ||
| SkipTLSVerify bool | ||
| } | ||
|
|
||
| // TokenResponse represents the structure of the token response | ||
| type TokenResponse struct { | ||
| AccessToken string `json:"access_token"` | ||
| TokenType string `json:"token_type"` | ||
| ExpiresIn int `json:"expires_in"` | ||
| } | ||
|
|
||
| // NewTokenConfig creates a configuration from environment variables | ||
| func NewTokenConfig() *TokenConfig { | ||
| skipTlsVerify, _ := strconv.ParseBool(getEnv("SKIP_TLS_VERIFY", "false")) | ||
| return &TokenConfig{ | ||
| BaseURL: getEnv("BASE_URL", "https://localhost:9443"), | ||
| ClientID: getEnv("CLIENT_ID", ""), | ||
| ServiceAccount: getEnv("SERVICE_ACCOUNT", ""), | ||
| ServiceToken: getEnv("SERVICE_TOKEN", ""), | ||
| SkipTLSVerify: skipTlsVerify, | ||
| } | ||
| } | ||
|
|
||
| // getEnv retrieves an environment variable with a default value | ||
| func getEnv(key, defaultValue string) string { | ||
| value := os.Getenv(key) | ||
| if value == "" { | ||
| return defaultValue | ||
| } | ||
| return value | ||
| } | ||
|
|
||
| // getAccessToken retrieves an access token from the specified endpoint | ||
| func getAccessToken(config *TokenConfig) (*TokenResponse, error) { | ||
| // Validate required configuration | ||
| if config.ClientID == "" || config.ServiceAccount == "" || config.ServiceToken == "" { | ||
| return nil, fmt.Errorf("missing required configuration") | ||
| } | ||
|
|
||
| // Create a custom HTTP client with optional TLS verification | ||
| tr := &http.Transport{ | ||
| TLSClientConfig: &tls.Config{InsecureSkipVerify: config.SkipTLSVerify}, | ||
| } | ||
| client := &http.Client{Transport: tr} | ||
|
|
||
| // Prepare the request body | ||
| data := url.Values{ | ||
| "grant_type": {"client_credentials"}, | ||
| "client_id": {config.ClientID}, | ||
| "username": {config.ServiceAccount}, | ||
| "password": {config.ServiceToken}, | ||
| "scope": {"profile"}, | ||
| } | ||
|
|
||
| // Create the HTTP request | ||
| fullURL := strings.TrimRight(config.BaseURL, "/") + "/application/o/token/" | ||
| req, err := http.NewRequest("POST", fullURL, strings.NewReader(data.Encode())) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("error creating request: %w", err) | ||
| } | ||
| req.Header.Set("Content-Type", "application/x-www-form-urlencoded") | ||
|
|
||
| // Send the request | ||
| resp, err := client.Do(req) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("error sending request: %w", err) | ||
| } | ||
| defer resp.Body.Close() | ||
|
|
||
| // Read the response body | ||
| body, err := io.ReadAll(resp.Body) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("error reading response: %w", err) | ||
| } | ||
|
|
||
| // Check for successful response | ||
| if resp.StatusCode != http.StatusOK { | ||
| return nil, fmt.Errorf("token retrieval failed (status %d): %s", | ||
| resp.StatusCode, string(body)) | ||
| } | ||
|
|
||
| // Parse the JSON response | ||
| var tokenResp TokenResponse | ||
| if err := json.Unmarshal(body, &tokenResp); err != nil { | ||
| return nil, fmt.Errorf("error parsing token response: %w\nRaw response: %s", err, string(body)) | ||
| } | ||
|
|
||
| return &tokenResp, nil | ||
| } | ||
|
|
||
| func main() { | ||
| // Load configuration from environment | ||
| config := NewTokenConfig() | ||
|
|
||
| // Retrieve access token | ||
| tokenResp, err := getAccessToken(config) | ||
| if err != nil { | ||
| log.Fatalf("Failed to obtain access token: %v", err) | ||
| } | ||
|
|
||
| // Print token details | ||
| fmt.Println("Access Token:", tokenResp.AccessToken) | ||
| fmt.Println("Token Type:", tokenResp.TokenType) | ||
| fmt.Println("Expires In:", tokenResp.ExpiresIn, "seconds") | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
|
|
||
| # Authentik OAuth Token Retrieval Client (M2M) | ||
|
|
||
| This repository provides an example implementation of a Machine-to-Machine (M2M) application using the [Authentik OAuth2 Client Credentials](https://docs.goauthentik.io/docs/add-secure-apps/providers/oauth2/client_credentials) provider. | ||
|
|
||
| ## Configuration | ||
|
|
||
| ### Environment Variables | ||
|
|
||
| The following environment variables must be set to configure the application: | ||
|
|
||
| - **`BASE_URL`**: | ||
| Base URL of the authentication server. | ||
| *Default*: `https://localhost:9443` | ||
| *Example*: `https://your-auth-server.com` | ||
|
|
||
| - **`CLIENT_ID`**: | ||
| OAuth client identifier. | ||
| *Required* (no default value). | ||
| *Example*: `WxUcBMGZdI7c0e5oYp6mYdEd64acpXSuWKh8zBH5` | ||
|
|
||
| - **`SERVICE_ACCOUNT`**: | ||
| Service account username. | ||
| *Required* (no default value). | ||
| *Example*: `test2test` | ||
|
|
||
| - **`SERVICE_TOKEN`**: | ||
| Service account password/token. | ||
| *Required* (no default value). | ||
| *Example*: `2Dzvbs5O7wjfaUj1k1YSqctRgVA5hDtsi18xIrmKeIn1pV0rn4G5nuuFQUwH` | ||
|
|
||
| - **`SKIP_TLS_VERIFY`**: | ||
| Disable TLS certificate verification. | ||
| *Default*: `false` | ||
|
|
||
| ## Usage | ||
|
|
||
| ### Setting Environment Variables | ||
|
|
||
| Set the required environment variables before running the application. For example: | ||
|
|
||
| ```bash | ||
| export BASE_URL=https://localhost:9443 | ||
| export CLIENT_ID=WxUcBMGZdI7c0e5oYp6mYdEd64acpXSuWKh8zBH5 | ||
| export SERVICE_ACCOUNT=test2test | ||
| export SERVICE_TOKEN=2Dzvbs5O7wjfaUj1k1YSqctRgVA5hDtsi18xIrmKeIn1pV0rn4G5nuuFQUwH | ||
| export SKIP_TLS_VERIFY=true | ||
| ``` | ||
|
|
||
| ## Running the script | ||
|
|
||
| Run the script using the following command: | ||
|
|
||
| `go run main.go` | ||
|
|
||
| Example Output | ||
|
|
||
| When the application is successfully run, you will see output similar to the following: | ||
|
|
||
| ``` | ||
| Access Token: <retrieved-access-token> | ||
| Token Type: Bearer | ||
| Expires In: 3600 seconds | ||
| ``` | ||
|
|
||
| The retrieved access token can then be used for authorized access to other resources. | ||
|
|
||
| For more details, refer to the [Authentik](https://goauthentik.io/) Documentation. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Build example