keycloak configuration

This commit is contained in:
renaldybrada
2026-02-18 09:21:29 +07:00
parent deb3337a8f
commit b0d8e64275
5 changed files with 37 additions and 12 deletions

No files matched your search

+7
View File
@@ -23,6 +23,13 @@ func LoadConfig() *Config {
Security: SecurityConfig{ Security: SecurityConfig{
TrustedOrigins: parseOrigins(getEnv("SECURITY_TRUSTED_ORIGINS", "http://localhost:3000,http://localhost:8080")), TrustedOrigins: parseOrigins(getEnv("SECURITY_TRUSTED_ORIGINS", "http://localhost:3000,http://localhost:8080")),
}, },
Keycloak: KeycloakConfig{
BaseUrl: getEnv("KEYCLOAK_BASE_URL", "https://auth.rssa.top"),
Realm: getEnv("KEYCLOAK_REALM", "sandbox"),
Audience: getEnv("KEYCLOAK_AUDIENCE", "akbar-test"),
Issuer: getEnv("KEYCLOAK_ISSUER", "https://auth.rssa.top/realms/sandbox"),
IsEnabled: getEnvAsBool("KEYCLOAK_IS_ENABLE", false),
},
} }
config.loadCustomDatabaseConfigs() config.loadCustomDatabaseConfigs()
+8
View File
@@ -47,6 +47,14 @@ func getEnvAsBoolFromMap(config map[string]string, key string, defaultValue bool
return defaultValue return defaultValue
} }
func getEnvAsBool(key string, defaultValue bool) bool {
valueStr := getEnv(key, "")
if value, err := strconv.ParseBool(valueStr); err == nil {
return value
}
return defaultValue
}
// Helper functions for getting default values based on database type // Helper functions for getting default values based on database type
func getDefaultPort(dbType string) int { func getDefaultPort(dbType string) int {
switch dbType { switch dbType {
+9
View File
@@ -7,6 +7,7 @@ type Config struct {
Databases map[string]DatabaseConfig Databases map[string]DatabaseConfig
ReadReplicas map[string][]DatabaseConfig ReadReplicas map[string][]DatabaseConfig
Security SecurityConfig Security SecurityConfig
Keycloak KeycloakConfig
} }
type ServerConfig struct { type ServerConfig struct {
@@ -48,3 +49,11 @@ type DatabaseConfig struct {
type SecurityConfig struct { type SecurityConfig struct {
TrustedOrigins []string `mapstructure:"trusted_origins"` TrustedOrigins []string `mapstructure:"trusted_origins"`
} }
type KeycloakConfig struct {
BaseUrl string
Realm string
Audience string
Issuer string
IsEnabled bool
}
+12 -11
View File
@@ -1,11 +1,11 @@
package middleware package middleware
import ( import (
"antrian-operasi/internal/config"
"antrian-operasi/internal/shared" "antrian-operasi/internal/shared"
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
"os"
"strings" "strings"
"time" "time"
@@ -14,16 +14,11 @@ import (
"github.com/golang-jwt/jwt/v4" "github.com/golang-jwt/jwt/v4"
) )
func AuthKeycloak() (gin.HandlerFunc, error) { func AuthKeycloak(cfg config.KeycloakConfig) (gin.HandlerFunc, error) {
baseURL := os.Getenv("KEYCLOAK_BASE_URL")
realm := os.Getenv("KEYCLOAK_REALM")
audience := os.Getenv("KEYCLOAK_AUDIENCE")
issuer := os.Getenv("KEYCLOAK_ISSUER")
jwksURL := fmt.Sprintf( jwksURL := fmt.Sprintf(
"%s/realms/%s/protocol/openid-connect/certs", "%s/realms/%s/protocol/openid-connect/certs",
baseURL, cfg.BaseUrl,
realm, cfg.Realm,
) )
jwks, err := keyfunc.Get(jwksURL, keyfunc.Options{ jwks, err := keyfunc.Get(jwksURL, keyfunc.Options{
@@ -37,6 +32,12 @@ func AuthKeycloak() (gin.HandlerFunc, error) {
} }
return func(c *gin.Context) { return func(c *gin.Context) {
// bypassing keycloak validation, if not enabled
if !cfg.IsEnabled {
log.Println("bypassing keycloak validation")
c.Next()
}
errorResponse := shared.BaseErrorResponse{ errorResponse := shared.BaseErrorResponse{
Success: false, Success: false,
Code: 401, Code: 401,
@@ -63,14 +64,14 @@ func AuthKeycloak() (gin.HandlerFunc, error) {
// validate issuer // validate issuer
errorResponse.Message = "invalid keycloak configuration" errorResponse.Message = "invalid keycloak configuration"
if claims["iss"] != issuer { if claims["iss"] != cfg.Issuer {
errorResponse.Errors = []string{"invalid issuer"} errorResponse.Errors = []string{"invalid issuer"}
c.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse) c.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse)
return return
} }
// validate audience // validate audience
if !claims.VerifyAudience(audience, true) { if !claims.VerifyAudience(cfg.Audience, true) {
errorResponse.Errors = []string{"invalid audience"} errorResponse.Errors = []string{"invalid audience"}
c.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse) c.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse)
return return
+1 -1
View File
@@ -35,7 +35,7 @@ func RegisterRoutes(cfg *config.Config, dbService database.Service) *gin.Engine
// init middleware // init middleware
router.Use(middleware.SecureCORSConfig(cfg.Security)) router.Use(middleware.SecureCORSConfig(cfg.Security))
authKeycloak, err := middleware.AuthKeycloak() authKeycloak, err := middleware.AuthKeycloak(cfg.Keycloak)
if err != nil { if err != nil {
log.Fatalf("Unable to initiate keycloak auth") log.Fatalf("Unable to initiate keycloak auth")
} }