* feat: kubesphere 4.0 Signed-off-by: ci-bot <ci-bot@kubesphere.io> * feat: kubesphere 4.0 Signed-off-by: ci-bot <ci-bot@kubesphere.io> --------- Signed-off-by: ci-bot <ci-bot@kubesphere.io> Co-authored-by: ks-ci-bot <ks-ci-bot@example.com> Co-authored-by: joyceliu <joyceliu@yunify.com>
61 lines
2.2 KiB
Go
61 lines
2.2 KiB
Go
/*
|
|
* Please refer to the LICENSE file in the root directory of the project.
|
|
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
|
*/
|
|
|
|
package basic
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"k8s.io/apiserver/pkg/authentication/authenticator"
|
|
"k8s.io/apiserver/pkg/authentication/user"
|
|
"k8s.io/klog/v2"
|
|
iamv1beta1 "kubesphere.io/api/iam/v1beta1"
|
|
|
|
"kubesphere.io/kubesphere/pkg/apiserver/authentication/request/basictoken"
|
|
"kubesphere.io/kubesphere/pkg/apiserver/request"
|
|
"kubesphere.io/kubesphere/pkg/models/auth"
|
|
)
|
|
|
|
// TokenAuthenticator implements kubernetes token authenticate interface with our custom logic.
|
|
// TokenAuthenticator will retrieve user info from cache by given token. If empty or invalid token
|
|
// was given, authenticator will still give passed response at the condition user will be user.Anonymous
|
|
// and group from user.AllUnauthenticated. This helps requests be passed along the handler chain,
|
|
// because some resources are public accessible.
|
|
type basicAuthenticator struct {
|
|
authenticator auth.PasswordAuthenticator
|
|
loginRecorder auth.LoginRecorder
|
|
}
|
|
|
|
func NewBasicAuthenticator(authenticator auth.PasswordAuthenticator, loginRecorder auth.LoginRecorder) basictoken.Password {
|
|
return &basicAuthenticator{
|
|
authenticator: authenticator,
|
|
loginRecorder: loginRecorder,
|
|
}
|
|
}
|
|
|
|
func (t *basicAuthenticator) AuthenticatePassword(ctx context.Context, username, password string) (*authenticator.Response, bool, error) {
|
|
authenticated, err := t.authenticator.Authenticate(ctx, "", username, password)
|
|
if err != nil {
|
|
if t.loginRecorder != nil && errors.Is(err, auth.IncorrectPasswordError) {
|
|
var sourceIP, userAgent string
|
|
if requestInfo, ok := request.RequestInfoFrom(ctx); ok {
|
|
sourceIP = requestInfo.SourceIP
|
|
userAgent = requestInfo.UserAgent
|
|
}
|
|
if err := t.loginRecorder.RecordLogin(ctx, username, iamv1beta1.Password, "", sourceIP, userAgent, err); err != nil {
|
|
klog.Errorf("Failed to record unsuccessful login attempt for user %s, error: %v", username, err)
|
|
}
|
|
}
|
|
return nil, false, err
|
|
}
|
|
return &authenticator.Response{
|
|
User: &user.DefaultInfo{
|
|
Name: authenticated.GetName(),
|
|
Groups: append(authenticated.GetGroups(), user.AllAuthenticated),
|
|
},
|
|
}, true, nil
|
|
}
|