forked from baron/baron-sso
Devfront를 위한 OIDC 프록시 엔드포인트 구현
This commit is contained in:
@@ -1526,7 +1526,7 @@ func (h *AuthHandler) PasswordLogin(c *fiber.Ctx) error {
|
||||
loginID := strings.TrimSpace(req.LoginID)
|
||||
ale.LoginIDs["loginId"] = req.LoginID // 원문
|
||||
ale.LoginIDs["loginId_normalized"] = loginID
|
||||
ale.NewPassword = req.Password // For test only, logging password (sensitive)
|
||||
// ale.NewPassword = req.Password // For test only, logging password (sensitive)
|
||||
|
||||
ale.Log(slog.LevelInfo, "Attempting to login")
|
||||
|
||||
@@ -1568,22 +1568,25 @@ func (h *AuthHandler) PasswordLogin(c *fiber.Ctx) error {
|
||||
|
||||
// --- OIDC 로그인 흐름 처리 ---
|
||||
if req.LoginChallenge != "" {
|
||||
slog.Info("OIDC login flow detected", "challenge", req.LoginChallenge)
|
||||
slog.Info("OIDC login flow detected", "challenge", req.LoginChallenge, "subject", subject)
|
||||
|
||||
// Check if the client is active
|
||||
loginReq, err := h.Hydra.GetLoginRequest(c.Context(), req.LoginChallenge)
|
||||
if err == nil && loginReq != nil && loginReq.Client.Metadata != nil {
|
||||
if status, ok := loginReq.Client.Metadata["status"].(string); ok {
|
||||
if strings.ToLower(status) == "inactive" {
|
||||
slog.Warn("Login rejected for inactive client in PasswordLogin", "client_id", loginReq.Client.ClientID)
|
||||
return fiber.NewError(fiber.StatusForbidden, "The client application is disabled.")
|
||||
if err == nil && loginReq != nil {
|
||||
slog.Info("OIDC Client Info", "client_id", loginReq.Client.ClientID, "name", loginReq.Client.ClientName)
|
||||
if loginReq.Client.Metadata != nil {
|
||||
if status, ok := loginReq.Client.Metadata["status"].(string); ok {
|
||||
if strings.ToLower(status) == "inactive" {
|
||||
slog.Warn("Login rejected for inactive client in PasswordLogin", "client_id", loginReq.Client.ClientID)
|
||||
return fiber.NewError(fiber.StatusForbidden, "The client application is disabled.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
acceptResp, err := h.Hydra.AcceptLoginRequest(c.Context(), req.LoginChallenge, subject)
|
||||
if err != nil {
|
||||
slog.Error("failed to accept hydra login request", "error", err)
|
||||
slog.Error("failed to accept hydra login request", "error", err, "challenge", req.LoginChallenge)
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to accept OIDC login request")
|
||||
}
|
||||
slog.Info("Hydra login request accepted", "redirectTo", acceptResp.RedirectTo)
|
||||
@@ -2480,7 +2483,56 @@ func (h *AuthHandler) formatPhoneForStorage(phone string) string {
|
||||
return phone
|
||||
}
|
||||
|
||||
// GetMe - Returns current user's profile with enriched data from local DB
|
||||
// ProxyOidc - 프론트엔드의 OIDC 요청을 내부 Hydra 서비스로 프록시합니다.
|
||||
func (h *AuthHandler) ProxyOidc(c *fiber.Ctx) error {
|
||||
path := c.Params("*")
|
||||
// [Strict] Always use internal Docker network address for proxying to avoid external loops
|
||||
targetURL := "http://hydra:4444"
|
||||
|
||||
// 프록시 URL 구성
|
||||
u, err := url.Parse(targetURL)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "invalid hydra public url")
|
||||
}
|
||||
u.Path = strings.TrimRight(u.Path, "/") + "/" + path
|
||||
u.RawQuery = string(c.Request().URI().QueryString())
|
||||
|
||||
slog.Debug("Proxying OIDC request", "from", c.Path(), "to", u.String())
|
||||
|
||||
// 요청 준비
|
||||
req, err := http.NewRequestWithContext(c.Context(), c.Method(), u.String(), bytes.NewReader(c.Body()))
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "failed to create proxy request")
|
||||
}
|
||||
|
||||
// 헤더 복사
|
||||
c.Request().Header.VisitAll(func(key, value []byte) {
|
||||
k := string(key)
|
||||
if k != "Host" && k != "Connection" {
|
||||
req.Header.Add(k, string(value))
|
||||
}
|
||||
})
|
||||
|
||||
// 요청 실행 (Hydra 내부 HttpClient 사용)
|
||||
resp, err := h.Hydra.HttpClient().Do(req)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusServiceUnavailable, "hydra public api unavailable")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 응답 헤더 복사
|
||||
for k, values := range resp.Header {
|
||||
for _, v := range values {
|
||||
c.Set(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
// 상태 코드 및 바디 설정
|
||||
c.Status(resp.StatusCode)
|
||||
_, err = io.Copy(c.Response().BodyWriter(), resp.Body)
|
||||
return err
|
||||
}
|
||||
|
||||
func (h *AuthHandler) GetMe(c *fiber.Ctx) error {
|
||||
profile, err := h.resolveCurrentProfile(c)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user