auth.go 1.91 KB
Newer Older
1 2 3 4 5 6 7 8
package middleware

import (
	"encoding/json"
	"io"
	"net/http"

	"github.com/gin-gonic/gin"
9
	"github.com/rs/zerolog/log"
10 11 12 13 14 15 16 17 18 19 20
	"gitlab.com/tensorsecurity-rd/waf-console/internal/utils"
)

const (
	// Cookie name to check for the auth token
	AuthCookieName = "auth_token"
)

// AuthMiddleware validates the auth cookie with SSO service
func AuthMiddleware(ssoUrl string) gin.HandlerFunc {
	return func(c *gin.Context) {
21 22 23 24 25
		// skip ping
		if c.Request.URL.Path != "/ping" {
			c.Next()
			return
		}
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
		// Get auth cookie
		cookies := c.Request.Cookies()
		if len(cookies) == 0 {
			utils.AssembleResponse(c, nil, utils.ErrUnauthorized)
			c.Abort()
			return
		}

		// Create request to SSO service
		req, err := http.NewRequest(http.MethodPost, ssoUrl, nil)
		if err != nil {
			utils.AssembleResponse(c, nil, utils.ErrInternalServer)
			c.Abort()
			return
		}

		// Add auth cookie to request
		for _, cookie := range cookies {
			req.AddCookie(cookie)
		}

		// Make request to SSO service
		client := &http.Client{}
		resp, err := client.Do(req)
		if err != nil {
			utils.AssembleResponse(c, nil, utils.ErrInternalServer)
			c.Abort()
			return
		}
		defer resp.Body.Close()

		// Read response body
		body, err := io.ReadAll(resp.Body)
		if err != nil {
60
			log.Error().Err(err).Msg("failed to read sso response body")
61 62 63 64 65 66 67 68
			utils.AssembleResponse(c, nil, utils.ErrInternalServer)
			c.Abort()
			return
		}

		// Parse SSO response
		var ssoResp SSOResponse
		if err := json.Unmarshal(body, &ssoResp); err != nil {
69
			log.Error().Err(err).Msg("failed to unmarshal sso response")
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
			utils.AssembleResponse(c, nil, utils.ErrInternalServer)
			c.Abort()
			return
		}

		// Check if authentication was successful
		if ssoResp.Code != "OK" {
			utils.AssembleResponse(c, nil, utils.ErrUnauthorized)
			c.Abort()
			return
		}

		// Store user info in context for later use
		c.Set("userInfo", ssoResp.Data)

		// Authentication successful, continue
		c.Next()
	}
}