/
auth.go
79 lines (64 loc) · 2.2 KB
/
auth.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package service
import (
"context"
"net/http"
"strings"
jwt "github.com/golang-jwt/jwt"
"github.com/rockbears/log"
"github.com/ovh/cds/sdk"
)
const JWTCookieName = "jwt_token"
type contextKey int
const (
ContextJWT contextKey = iota
ContextJWTRaw
ContextJWTFromCookie
ContextSessionID
)
func NoAuthMiddleware(ctx context.Context, _ http.ResponseWriter, _ *http.Request, _ *HandlerConfig) (context.Context, error) {
return ctx, nil
}
func JWTMiddleware(ctx context.Context, _ http.ResponseWriter, req *http.Request, _ *HandlerConfig, keyFunc jwt.Keyfunc) (context.Context, error) {
var jwtRaw string
var jwtFromCookie bool
// Try to get the jwt from the cookie firstly then from the authorization bearer header, a XSRF token with cookie
jwtCookie, _ := req.Cookie(JWTCookieName)
if jwtCookie != nil {
jwtRaw = jwtCookie.Value
jwtFromCookie = true
} else if strings.HasPrefix(req.Header.Get("Authorization"), "Bearer ") {
jwtRaw = strings.TrimPrefix(req.Header.Get("Authorization"), "Bearer ")
}
// If no jwt is given, simply return empty context without error
if jwtRaw == "" {
return ctx, nil
}
jwt, claims, err := CheckSessionJWT(jwtRaw, keyFunc)
if err != nil {
// If the given JWT is not valid log the error and return
log.Warn(ctx, "service.JWTMiddleware> invalid given jwt token [%s]: %+v", req.URL.String(), err)
return ctx, nil
}
ctx = context.WithValue(ctx, ContextJWTRaw, jwt)
ctx = context.WithValue(ctx, ContextJWT, jwt)
ctx = context.WithValue(ctx, ContextJWTFromCookie, jwtFromCookie)
ctx = context.WithValue(ctx, ContextSessionID, claims.ID)
return ctx, nil
}
// CheckSessionJWT validate given session jwt token.
func CheckSessionJWT(jwtToken string, keyFunc jwt.Keyfunc) (*jwt.Token, *sdk.AuthSessionJWTClaims, error) {
token, err := jwt.ParseWithClaims(jwtToken, &sdk.AuthSessionJWTClaims{}, keyFunc)
if err != nil {
return nil, nil, sdk.NewErrorWithStack(err, sdk.ErrUnauthorized)
}
claims, ok := token.Claims.(*sdk.AuthSessionJWTClaims)
if ok && token.Valid {
return token, claims, nil
}
return nil, nil, sdk.WithStack(sdk.ErrUnauthorized)
}
func OverrideAuth(m Middleware) HandlerConfigParam {
return func(rc *HandlerConfig) {
rc.OverrideAuthMiddleware = m
}
}