@@ -4,7 +4,7 @@ package basic
4
4
5
5
import (
6
6
"context"
7
- "crypto/sha256 "
7
+ "crypto"
8
8
"encoding/hex"
9
9
"errors"
10
10
"fmt"
@@ -27,9 +27,9 @@ var ErrInvalidCredentials = errors.New("basic: Invalid user credentials")
27
27
// commonly used when enable/add strategy to go-guardian authenticator.
28
28
const StrategyKey = auth .StrategyKey ("Basic.Strategy" )
29
29
30
- // ExtensionKey represents a key for the hashed password in info extensions.
30
+ // ExtensionKey represents a key for the password in info extensions.
31
31
// Typically used when basic strategy cache the authentication decisions.
32
- const ExtensionKey = "x-go-guardian-basic-hash "
32
+ const ExtensionKey = "x-go-guardian-basic-password "
33
33
34
34
// AuthenticateFunc declare custom function to authenticate request using user credentials.
35
35
// the authenticate function invoked by Authenticate Strategy method after extracting user credentials
@@ -65,8 +65,9 @@ func (auth AuthenticateFunc) credentials(r *http.Request) (string, string, error
65
65
}
66
66
67
67
type cachedBasic struct {
68
- cache store.Cache
69
- authFunc AuthenticateFunc
68
+ AuthenticateFunc
69
+ hash crypto.Hash
70
+ cache store.Cache
70
71
}
71
72
72
73
func (c * cachedBasic ) authenticate (ctx context.Context , r * http.Request , userName , pass string ) (auth.Info , error ) { // nolint:lll
@@ -87,18 +88,18 @@ func (c *cachedBasic) authenticate(ctx context.Context, r *http.Request, userNam
87
88
88
89
info := v .(auth.Info )
89
90
ext := info .Extensions ()
90
- hash , ok := ext [ExtensionKey ]
91
+ hashedPass , ok := ext [ExtensionKey ]
91
92
92
93
if ! ok {
93
94
return c .authenticatAndHash (ctx , r , userName , pass )
94
95
}
95
96
96
- err = password (pass ).compare (hash [0 ])
97
+ err = password (pass ).compare (c . hash , hashedPass [0 ])
97
98
return info , err
98
99
}
99
100
100
101
func (c * cachedBasic ) authenticatAndHash (ctx context.Context , r * http.Request , userName , pass string ) (auth.Info , error ) { //nolint:lll
101
- info , err := c .authFunc (ctx , r , userName , pass )
102
+ info , err := c .AuthenticateFunc (ctx , r , userName , pass )
102
103
if err != nil {
103
104
return nil , err
104
105
}
@@ -108,8 +109,8 @@ func (c *cachedBasic) authenticatAndHash(ctx context.Context, r *http.Request, u
108
109
ext = make (map [string ][]string )
109
110
}
110
111
111
- hash := password (pass ).hash ()
112
- ext [ExtensionKey ] = []string {hash }
112
+ hashedPass := password (pass ).hash (c . hash )
113
+ ext [ExtensionKey ] = []string {hashedPass }
113
114
info .SetExtensions (ext )
114
115
115
116
// cache result
@@ -123,25 +124,49 @@ func (c *cachedBasic) authenticatAndHash(ctx context.Context, r *http.Request, u
123
124
// New return new auth.Strategy.
124
125
// The returned strategy, caches the invocation result of authenticate function.
125
126
func New (f AuthenticateFunc , cache store.Cache ) auth.Strategy {
127
+ return NewWithOptions (f , cache )
128
+ }
129
+
130
+ // NewWithOptions return new auth.Strategy.
131
+ // The returned strategy, caches the invocation result of authenticate function.
132
+ func NewWithOptions (f AuthenticateFunc , cache store.Cache , opts ... auth.Option ) auth.Strategy {
126
133
cb := & cachedBasic {
127
- authFunc : f ,
128
- cache : cache ,
134
+ AuthenticateFunc : f ,
135
+ cache : cache ,
136
+ }
137
+
138
+ for _ , opt := range opts {
139
+ opt .Apply (cb )
129
140
}
130
141
131
142
return AuthenticateFunc (cb .authenticate )
132
143
}
133
144
145
+ // SetHash set the hashing algorithm to hash the user password.
146
+ func SetHash (h crypto.Hash ) auth.Option {
147
+ return auth .OptionFunc (func (s auth.Strategy ) {
148
+ if v , ok := s .(* cachedBasic ); ok {
149
+ v .hash = h
150
+ }
151
+ })
152
+ }
153
+
134
154
type password string
135
155
136
- func (p password ) hash () string {
137
- sha := sha256 .New ()
138
- _ , _ = sha .Write ([]byte (p ))
139
- sum := sha .Sum (nil )
156
+ func (p password ) hash (h crypto.Hash ) string {
157
+ // check if allow to hash, otherwise return plain password.
158
+ if h < crypto .MD4 {
159
+ return string (p )
160
+ }
161
+
162
+ hasher := h .New ()
163
+ _ , _ = hasher .Write ([]byte (p ))
164
+ sum := hasher .Sum (nil )
140
165
return hex .EncodeToString (sum )
141
166
}
142
167
143
- func (p password ) compare (hash string ) error {
144
- if p .hash () == hash {
168
+ func (p password ) compare (h crypto. Hash , hashedPass string ) error {
169
+ if p .hash (h ) == hashedPass {
145
170
return nil
146
171
}
147
172
return ErrInvalidCredentials
0 commit comments