oidc-forward-auth/pkg/forwardauth/cookies.go
2020-06-04 18:14:16 +02:00

107 lines
2.8 KiB
Go

/*
Copyright (c) 2020 Stefan Kürzeder <info@stivik.de>
This code is licensed under MIT license (see LICENSE for details)
*/
package forwardauth
import (
"errors"
"fmt"
"net/http"
"regexp"
"strings"
"time"
"github.com/StiviiK/keycloak-traefik-forward-auth/pkg/options"
)
func getBaseCookie(options *options.Options) *http.Cookie {
return &http.Cookie{
Path: "/",
Domain: options.CookieDomain,
HttpOnly: true,
Secure: true,
}
}
func (fw *ForwardAuth) MakeCSRFCookie(w http.ResponseWriter, r *http.Request, options *options.Options, redirect string, state string) *http.Cookie {
cookie := getBaseCookie(options)
cookie.Name = "__auth_csrf"
cookie.Value = fmt.Sprintf("%s|%s", redirect, state)
cookie.Expires = time.Now().Local().Add(time.Hour)
return cookie
}
func (fw *ForwardAuth) ValidateCSRFCookie(r *http.Request) (state string, redirect string, error error) {
csrfCookie, err := r.Cookie("__auth_csrf")
if err != nil {
return "", "", errors.New("Missing csrf cookie")
}
rExpression, err := regexp.Compile("^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$")
if err != nil {
return "", "", err
}
data := strings.Split(csrfCookie.Value, "|")
if len(data) != 2 {
return "", "", errors.New("Invalid csrf value")
}
if !rExpression.MatchString(data[1]) {
return "", "", errors.New("Invalid state")
}
return data[1], data[0], nil
}
func (fw *ForwardAuth) ClearCSRFCookie(options *options.Options) *http.Cookie {
cookie := getBaseCookie(options)
cookie.Name = "__auth_csrf"
cookie.Expires = time.Now().Local().Add(time.Hour * -1)
return cookie
}
func (fw *ForwardAuth) MakeAuthCookie(options *options.Options, authResult *AuthenticatationResult) *http.Cookie {
cookie := getBaseCookie(options)
cookie.Name = "__auth"
cookie.Value = authResult.IDToken
cookie.Expires = time.Now().Local().Add(time.Hour * 24)
return cookie
}
func (fw *ForwardAuth) GetAuthCookie(r *http.Request) (*http.Cookie, error) {
return r.Cookie("__auth")
}
func (fw *ForwardAuth) ClearAuthCookie(options *options.Options) *http.Cookie {
cookie := getBaseCookie(options)
cookie.Name = "__auth"
cookie.Expires = time.Now().Local().Add(time.Hour * -1)
return cookie
}
func (fw *ForwardAuth) MakeRefreshAuthCookie(options *options.Options, authResult *AuthenticatationResult) *http.Cookie {
cookie := getBaseCookie(options)
cookie.Name = "__auth_refresh"
cookie.Value = authResult.RefreshToken
cookie.Expires = time.Now().Local().Add(time.Hour * 24)
return cookie
}
func (fw *ForwardAuth) GetRefreshAuthCookie(r *http.Request) (*http.Cookie, error) {
return r.Cookie("__auth_refresh")
}
func (fw *ForwardAuth) ClearRefreshAuthCookie(options *options.Options) *http.Cookie {
cookie := getBaseCookie(options)
cookie.Name = "__auth_refresh"
cookie.Expires = time.Now().Local().Add(time.Hour * -1)
return cookie
}