Add api for identity provider login (#5534)
* add api for ldap login * update ldap login to identity provider login for more flexible login type Signed-off-by: wenhaozhou <wenhaozhou@yunify.com> * update PasswordAuthenticate Signed-off-by: wenhaozhou <wenhaozhou@yunify.com> * add test case Signed-off-by: wenhaozhou <wenhaozhou@yunify.com> * update api path Signed-off-by: wenhaozhou <wenhaozhou@yunify.com> * make goimports and add annotations Signed-off-by: wenhaozhou <wenhaozhou@yunify.com> * update func names & add annotations Signed-off-by: wenhaozhou <wenhaozhou@yunify.com> --------- Signed-off-by: wenhaozhou <wenhaozhou@yunify.com>
This commit is contained in:
@@ -355,16 +355,6 @@ func (h *handler) oauthCallback(req *restful.Request, response *restful.Response
|
||||
response.WriteEntity(result)
|
||||
}
|
||||
|
||||
func (h *handler) login(request *restful.Request, response *restful.Response) {
|
||||
var loginRequest LoginRequest
|
||||
err := request.ReadEntity(&loginRequest)
|
||||
if err != nil {
|
||||
api.HandleBadRequest(response, request, err)
|
||||
return
|
||||
}
|
||||
h.passwordGrant(loginRequest.Username, loginRequest.Password, request, response)
|
||||
}
|
||||
|
||||
// To obtain an Access Token, an ID Token, and optionally a Refresh Token,
|
||||
// the RP (Client) sends a Token Request to the Token Endpoint to obtain a Token Response,
|
||||
// as described in Section 3.2 of OAuth 2.0 [RFC6749], when using the Authorization Code Flow.
|
||||
@@ -406,7 +396,7 @@ func (h *handler) token(req *restful.Request, response *restful.Response) {
|
||||
case grantTypePassword:
|
||||
username, _ := req.BodyParameter("username")
|
||||
password, _ := req.BodyParameter("password")
|
||||
h.passwordGrant(username, password, req, response)
|
||||
h.passwordGrant("", username, password, req, response)
|
||||
return
|
||||
case grantTypeRefreshToken:
|
||||
h.refreshTokenGrant(req, response)
|
||||
@@ -427,8 +417,8 @@ func (h *handler) token(req *restful.Request, response *restful.Response) {
|
||||
// such as the device operating system or a highly privileged application.
|
||||
// The authorization server should take special care when enabling this
|
||||
// grant type and only allow it when other flows are not viable.
|
||||
func (h *handler) passwordGrant(username string, password string, req *restful.Request, response *restful.Response) {
|
||||
authenticated, provider, err := h.passwordAuthenticator.Authenticate(req.Request.Context(), username, password)
|
||||
func (h *handler) passwordGrant(provider, username string, password string, req *restful.Request, response *restful.Response) {
|
||||
authenticated, provider, err := h.passwordAuthenticator.Authenticate(req.Request.Context(), provider, username, password)
|
||||
if err != nil {
|
||||
switch err {
|
||||
case auth.AccountIsNotActiveError:
|
||||
@@ -682,3 +672,11 @@ func (h *handler) userinfo(req *restful.Request, response *restful.Response) {
|
||||
}
|
||||
response.WriteEntity(result)
|
||||
}
|
||||
|
||||
func (h *handler) loginByIdentityProvider(req *restful.Request, response *restful.Response) {
|
||||
username, _ := req.BodyParameter("username")
|
||||
password, _ := req.BodyParameter("password")
|
||||
idp := req.PathParameter("identiyprovider")
|
||||
|
||||
h.passwordGrant(idp, username, password, req, response)
|
||||
}
|
||||
|
||||
@@ -158,22 +158,17 @@ func AddToContainer(c *restful.Container, im im.IdentityManagementInterface,
|
||||
Returns(http.StatusOK, http.StatusText(http.StatusOK), "").
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AuthenticationTag}))
|
||||
|
||||
c.Add(ws)
|
||||
|
||||
// legacy auth API
|
||||
legacy := &restful.WebService{}
|
||||
legacy.Path("/kapis/iam.kubesphere.io/v1alpha2/login").
|
||||
Consumes(restful.MIME_JSON).
|
||||
Produces(restful.MIME_JSON)
|
||||
legacy.Route(legacy.POST("").
|
||||
To(handler.login).
|
||||
Deprecate().
|
||||
Doc("KubeSphere APIs support token-based authentication via the Authtoken request header. The POST Login API is used to retrieve the authentication token. After the authentication token is obtained, it must be inserted into the Authtoken header for all requests.").
|
||||
Reads(LoginRequest{}).
|
||||
Returns(http.StatusOK, api.StatusOK, oauth.Token{}).
|
||||
ws.Route(ws.POST("/login/{identityprovider}").
|
||||
Consumes(contentTypeFormData).
|
||||
Doc("Login by identity provider user").
|
||||
Param(ws.PathParameter("identityprovider", "The identity provider name")).
|
||||
Param(ws.FormParameter("username", "The username of the relevant user in ldap")).
|
||||
Param(ws.FormParameter("password", "The password of the relevant user in ldap")).
|
||||
To(handler.loginByIdentityProvider).
|
||||
Returns(http.StatusOK, http.StatusText(http.StatusOK), oauth.Token{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AuthenticationTag}))
|
||||
|
||||
c.Add(legacy)
|
||||
c.Add(ws)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user