Skip to content

Commit

Permalink
remove source ip validation
Browse files Browse the repository at this point in the history
  • Loading branch information
lsjostro committed Feb 8, 2024
1 parent 6a0db58 commit b718108
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 57 deletions.
63 changes: 12 additions & 51 deletions authz/authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"golang.org/x/net/http2"
rpcstatus "google.golang.org/genproto/googleapis/rpc/status"
"google.golang.org/protobuf/types/known/timestamppb"

pb "github.com/shelmangroup/envoy-oidc-authserver/internal/gen/session/v1"
"github.com/shelmangroup/envoy-oidc-authserver/session"
Expand Down Expand Up @@ -139,16 +138,15 @@ func (s *Service) authProcess(ctx context.Context, req *auth.AttributeContext_Ht
var headers []*core.HeaderValueOption
var sessionData *pb.SessionData
sessionCookieName := provider.CookieNamePrefix + "-" + ServiceName
sourceIP := realIP(req.GetHeaders())

requestedURL := req.GetScheme() + "://" + req.GetHost() + req.GetPath()
slog.Debug("client request url", slog.String("url", requestedURL))

// check if cookie exists and fetch session data from cookie
sessionData, sessionId := s.getSessionCookieData(ctx, req, sourceIP, sessionCookieName)
sessionData, sessionId := s.getSessionCookieData(ctx, req, sessionCookieName)
if sessionData == nil || sessionId == "" {
slog.Debug("session data not found in cookie, creating new")
headers, err := s.newSession(ctx, sourceIP, requestedURL, sessionCookieName, provider)
headers, err := s.newSession(ctx, requestedURL, sessionCookieName, provider)
if err != nil {
return nil, err
}
Expand All @@ -173,7 +171,7 @@ func (s *Service) authProcess(ctx context.Context, req *auth.AttributeContext_Ht
err := s.validateTokens(ctx, provider, sessionData, sessionCookieName, sessionId)
if err != nil {
slog.Warn("couldn't validating tokens", slog.String("err", err.Error()))
headers, err := s.newSession(ctx, sourceIP, requestedURL, sessionCookieName, provider)
headers, err := s.newSession(ctx, requestedURL, sessionCookieName, provider)
if err != nil {
return nil, err
}
Expand All @@ -199,16 +197,12 @@ func (s *Service) retriveTokens(ctx context.Context, provider *OIDCProvider, ses
sessionData.RefreshToken = tokens.RefreshToken
sessionData.AccessToken = tokens.AccessToken
sessionData.IdToken = tokens.IDToken
sessionData.Expiry = timestamppb.New(tokens.Expiry)

// slog.Debug("successfully acquried tokens, now storing it to session cookie", slog.Any("sessionData", sessionData))

enc, err := session.EncodeToken(ctx, [32]byte(s.secretKey), sessionData)
if err != nil {
slog.Error("error encrypting session data", slog.String("err", err.Error()))
return err
}
slog.Debug("Encrypted SessionData", slog.Int("byte_len", len(enc)))

// store session data in cache
if err := s.store.Set(ctx, sessionId, enc); err != nil {
Expand All @@ -228,6 +222,7 @@ func (s *Service) validateTokens(ctx context.Context, provider *OIDCProvider, d
return nil
}

slog.Debug("Token expired, refreshing token...")
if expired && d.RefreshToken == "" {
return errors.New("token expired and no refresh token found, add scope=offline_access to the auth request to get a refresh token")
}
Expand All @@ -239,9 +234,8 @@ func (s *Service) validateTokens(ctx context.Context, provider *OIDCProvider, d
d.RefreshToken = t.RefreshToken
d.AccessToken = t.AccessToken
d.IdToken = t.IDToken
d.Expiry = timestamppb.New(t.Expiry)

slog.Debug("Token refreshed, updating session cookie", slog.String("expire", t.Expiry.String()))
slog.Debug("Token refreshed, updating session")
enc, err := session.EncodeToken(ctx, [32]byte(s.secretKey), d)
if err != nil {
slog.Error("error encrypting session data", slog.String("err", err.Error()))
Expand All @@ -255,7 +249,7 @@ func (s *Service) validateTokens(ctx context.Context, provider *OIDCProvider, d
return nil
}

func (s *Service) newSession(ctx context.Context, sourceIP, requestedURL, sessionCookieName string, provider *OIDCProvider) ([]*core.HeaderValueOption, error) {
func (s *Service) newSession(ctx context.Context, requestedURL, sessionCookieName string, provider *OIDCProvider) ([]*core.HeaderValueOption, error) {
slog.Debug("Creating new session")
var headers []*core.HeaderValueOption

Expand All @@ -266,7 +260,6 @@ func (s *Service) newSession(ctx context.Context, sourceIP, requestedURL, sessio
}
slog.Debug("setting requested url", slog.String("requested_url", requestedURL))
sessionData.RequestedUrl = requestedURL
sessionData.SourceIp = sourceIP

enc, err := session.EncodeToken(ctx, [32]byte(s.secretKey), sessionData)
if err != nil {
Expand All @@ -292,28 +285,26 @@ func (s *Service) newSession(ctx context.Context, sourceIP, requestedURL, sessio
return append(headers, s.setCookie(cookie)...), nil
}

func (s *Service) getSessionCookieData(ctx context.Context, req *auth.AttributeContext_HttpRequest, sourceIP, cookieName string) (*pb.SessionData, string) {
func (s *Service) getSessionCookieData(ctx context.Context, req *auth.AttributeContext_HttpRequest, cookieName string) (*pb.SessionData, string) {
var sessionData *pb.SessionData
var cookie *http.Cookie
var sessionId string

for _, c := range s.getCookies(req) {
if c.Name == cookieName {
if c.Valid() != nil {
return nil, ""
}
slog.Debug("found a cookie 👌", slog.String("cookie_name", c.Name))
cookie = c
sessionId = c.Value
}
}

if cookie == nil {
slog.Debug("no cookie found")
if sessionId == "" {
slog.Debug("no sessionId found in cookie")
return nil, ""
}

sessionId := cookie.Value
slog.Debug("client source ip", slog.String("session_id", sessionId), slog.String("ip", sourceIP))

slog.Debug("getting session data from session store", slog.String("session_id", sessionId))
d, err := s.store.Cache.Get(ctx, sessionId)
if err != nil {
slog.Error("error getting session data from cache", slog.String("err", err.Error()))
Expand All @@ -325,12 +316,6 @@ func (s *Service) getSessionCookieData(ctx context.Context, req *auth.AttributeC
slog.Error("error decrypt session data", slog.String("err", err.Error()))
return nil, ""
}
slog.Debug("getting session data from session cookie", slog.String("session_id", sessionId), slog.String("session_data_expiry", sessionData.Expiry.AsTime().String()))

if sessionData.SourceIp != sourceIP {
slog.Warn("source ip missmatch, re-auth needed!", slog.String("session_id", sessionId), slog.String("session_ip", sessionData.SourceIp), slog.String("req_ip", sourceIP))
return nil, ""
}

return sessionData, sessionId
}
Expand Down Expand Up @@ -428,27 +413,3 @@ func (s *Service) authResponse(success bool, httpStatusCode envoy_type.StatusCod
},
}
}

func realIP(headers map[string]string) string {
var ip string

var envoyExternalAddress = "x-envoy-external-address"
var xForwardedFor = "x-forwarded-for"
var xRealIP = "x-real-ip"

if tcip, ok := headers[envoyExternalAddress]; ok {
ip = tcip
} else if xrip, ok := headers[xRealIP]; ok {
ip = xrip
} else if xff, ok := headers[xForwardedFor]; ok {
i := strings.Index(xff, ",")
if i == -1 {
i = len(xff)
}
ip = xff[:i]
}
if ip == "" || net.ParseIP(ip) == nil {
return ""
}
return ip
}
3 changes: 2 additions & 1 deletion oidc/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,15 @@ func (o *OIDCProvider) IdpAuthURL(codeChallenge string) string {

func (o *OIDCProvider) VerifyTokens(ctx context.Context, accessToken, idToken string) (bool, error) {
var expired bool
_, err := rp.VerifyTokens[*oidc.IDTokenClaims](ctx, accessToken, idToken, o.provider.IDTokenVerifier())
t, err := rp.VerifyTokens[*oidc.IDTokenClaims](ctx, accessToken, idToken, o.provider.IDTokenVerifier())
if err != nil {
if err == oidc.ErrExpired {
expired = true
} else {
return false, err
}
}
slog.Debug("tokens verified", slog.String("expire", t.GetExpiration().String()))
return expired, nil
}

Expand Down
8 changes: 3 additions & 5 deletions proto/session/v1/session.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ message SessionData {
string requested_url = 1;
string code_verifier = 2;
string code_challenge = 3;
string source_ip = 4;
string access_token = 5;
string refresh_token = 6;
string id_token = 7;
google.protobuf.Timestamp expiry = 8;
string access_token = 4;
string refresh_token = 5;
string id_token = 6;
}

0 comments on commit b718108

Please sign in to comment.