Skip to content

Commit

Permalink
able to change password
Browse files Browse the repository at this point in the history
  • Loading branch information
tianxiaoliang committed Jun 28, 2020
1 parent bd88a19 commit 964cb02
Show file tree
Hide file tree
Showing 10 changed files with 230 additions and 153 deletions.
27 changes: 20 additions & 7 deletions docs/user-guides/rbac.md
Expand Up @@ -13,20 +13,23 @@ openssl rsa -in private.key -pubout -out public.key
```

2.edit app.conf

can revoke private.key after each cluster restart,
```ini
rbac_enabled = true
rbac_rsa_pub_key_file = ./public.key
rbac_rsa_public_key_file = ./public.key
rbac_rsa_private_key_file = ./private.key
```

before you start server, you need to set env to set your root account.
can revoke private.key after each cluster restart,can not revoke root name and password
3.root account
before you start server, you need to set env to set your root account password.
can not revoke password after cluster start
```sh
export SC_INIT_ROOT_USERNAME=root
export SC_INIT_ROOT_PASSWORD=rootpwd
export SC_INIT_PRIVATE_KEY=`cat private.key`
```
at the first time service center cluster init, it will use this env to setup rbac module.

the root account name is "root"

To securely distribute your root account and private key,
you can use kubernetes [secret](https://kubernetes.io/zh/docs/tasks/inject-data-application/distribute-credentials-secure/)
### Generate a token
Expand All @@ -50,4 +53,14 @@ for example:
curl -X GET \
'http://127.0.0.1:30100/v4/default/registry/microservices/{service-id}/instances' \
-H 'Authorization: Bear eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1OTI4OTQ1NTEsInVzZXIiOiJyb290In0.FfLOSvVmHT9qCZSe_6iPf4gNjbXLwCrkXxKHsdJoQ8w'
```
```

### Change password
You must supply current password and token to update to new password
curl -X PUT \
http://127.0.0.1:30100/v4/account-password \
-H 'Authorization: Bear eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50Ijoicm9vdCIsImV4cCI6MTU5MzMyOTE3OSwicm9sZSI6IiJ9.OR_uruuLds1wz10_J4gDEA-L9Ma_1RrHiKEA6CS-Nilv6hHB5KyhZ9_4qqf_c0iia4uKryAGHKsXUvrjOE51tz4QCXlgCmddrkYuLQsnDezXhV3TIqzdl4R_cy8h2cZo8O_b_q7eU2Iemd6x7BJE49SLgNiP5LTXCVct5Qm_GiXYTaM4dbHIJ01V-EPmNQuBr1vKdfNa8cqWtASSp9IEkFx1YpzhFacQgmfoiSGHvxQYZldQXuAh60ZXLBDexGu6jGnG39MqVNRysvHTpZRqxZWBhmEn5DeXpgKu-zlakJMjeEma4zcN-H0MumE-nMlBT5kjKWVr1DOdtOyJI6i786ZpS0wWHV4VOxpSursoKsW_XuTZCMM8LTBgdy5icCuHUXvvWXYJxPks9Pq3DcFjPlY3IuXyfokEWxGvrAF6jzglgSrNTiRkoNBKVktEapDyrpyWfktp22mhvWF6GuNoUzztxFPJblH-TXdudzWeqx-gV1lsRPSMsW8-oq6pxJfeb-b0PNM8vAIbwvv8an4T5iNMBZMz7J9NbpVCaj5eLcgfUXktyb8eWSfANhYMxY9kQN9dHZlkASAW-sjehi-rBXYJ8aCL4EbLzrYlmFWoN0z25dxvAxmWaPRQED3METYyZHvV_G4DSQf0cB2Oer_YdoRa6HWmxnTlz0HwPEq55PM' \
-d '{
"currentPassword":"rootpwd",
"password":"123"
}'
12 changes: 9 additions & 3 deletions pkg/model/account.go
Expand Up @@ -17,11 +17,17 @@

package model

const (
RoleAdmin = "admin"
RoleAuditor = "auditor"
)

type Account struct {
Name string `json:"name,omitempty"`
Password string `json:"password,omitempty"`
Name string `json:"name,omitempty"`
Password string `json:"password,omitempty"`
Role string `json:"role,omitempty"`
CurrentPassword string `json:"currentPassword,omitempty"`
}

type Token struct {
TokenStr string `json:"token,omitempty"`
}
22 changes: 15 additions & 7 deletions server/handler/auth/auth.go
Expand Up @@ -17,6 +17,7 @@
package auth

import (
"context"
"github.com/apache/servicecomb-service-center/pkg/chain"
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/rest"
Expand Down Expand Up @@ -63,15 +64,22 @@ func (h *Handler) Handle(i *chain.Invocation) {
}
to := s[1]
//TODO rbac
_, err := authr.Authenticate(i.Context(), to)
if err == nil {
log.Info("user access")
i.Next()
claims, err := authr.Authenticate(i.Context(), to)
if err != nil {
log.Errorf(err, "authenticate request failed, %s %s", req.Method, req.RequestURI)
controller.WriteError(w, scerr.ErrUnauthorized, err.Error())
i.Fail(nil)
return
}
log.Errorf(err, "authenticate request failed, %s %s", req.Method, req.RequestURI)
controller.WriteError(w, scerr.ErrUnauthorized, err.Error())
i.Fail(nil)
log.Info("user access")
req2 := req.WithContext(context.WithValue(req.Context(), "accountInfo", claims))

*req = *req2
log.Infof("%s", req.Context())
log.Infof("%s", req2.Context())
i.Next()
return

}
func mustAuth(req *http.Request) bool {
if strings.Contains(req.URL.Path, "/v4/token") {
Expand Down
46 changes: 46 additions & 0 deletions server/rest/controller/v4/auth_resource.go
Expand Up @@ -37,9 +37,55 @@ type AuthResource struct {
func (r *AuthResource) URLPatterns() []rest.Route {
return []rest.Route{
{http.MethodPost, "/v4/token", r.Login},
{http.MethodPut, "/v4/account-password", r.ChangePassword},
}
}
func (r *AuthResource) ChangePassword(w http.ResponseWriter, req *http.Request) {
body, err := ioutil.ReadAll(req.Body)
if err != nil {
log.Error("read body err", err)
controller.WriteError(w, scerror.ErrInternal, err.Error())
return
}
a := &model.Account{}
if err = json.Unmarshal(body, a); err != nil {
log.Error("json err", err)
controller.WriteError(w, scerror.ErrInvalidParams, err.Error())
return
}
if a.Password == "" {
controller.WriteError(w, scerror.ErrInvalidParams, "new password is empty")
return
}
claims := req.Context().Value("accountInfo")
m, ok := claims.(map[string]interface{})
if !ok {
log.Errorf(err, "claims convert failed: %T", claims)
controller.WriteError(w, scerror.ErrInvalidParams, "wrong account info")
return
}
accountNameI := m[rbac.ClaimsUser]
changer, ok := accountNameI.(string)
if !ok {
log.Error("can not convert claim", nil)
controller.WriteError(w, scerror.ErrInvalidParams, err.Error())
return
}
roleI := m[rbac.ClaimsRole]
role, ok := roleI.(string)
if !ok {
log.Error("can not convert claim", nil)
controller.WriteError(w, scerror.ErrInvalidParams, err.Error())
return
}

err = rbac.ChangePassword(context.TODO(), role, changer, a)
if err != nil {
log.Error("change password failed", err)
controller.WriteError(w, scerror.ErrInternal, err.Error())
return
}
}
func (r *AuthResource) Login(w http.ResponseWriter, req *http.Request) {
body, err := ioutil.ReadAll(req.Body)
if err != nil {
Expand Down
8 changes: 5 additions & 3 deletions server/service/rbac/authr_plugin.go
Expand Up @@ -31,7 +31,8 @@ import (
var ErrUnauthorized = errors.New("wrong user name or password")

const (
ClaimsUser = "user"
ClaimsUser = "account"
ClaimsRole = "role"
)

//EmbeddedAuthenticator is sc default auth plugin, RBAC data is persisted in etcd
Expand All @@ -57,12 +58,13 @@ func (a *EmbeddedAuthenticator) Login(ctx context.Context, user string, password
return "", err
}
if user == account.Name && password == account.Password {
secret, err := GetPrivateKey(ctx)
secret, err := GetPrivateKey()
if err != nil {
return "", err
}
tokenStr, err := token.Sign(map[string]interface{}{
ClaimsUser: user, //TODO more claims for RBAC, for example role name
ClaimsUser: user,
ClaimsRole: account.Role, //TODO more claims for RBAC, for example rule config
},
secret,
token.WithExpTime("30m"),
Expand Down
28 changes: 28 additions & 0 deletions server/service/rbac/dao/account_dao.go
Expand Up @@ -30,6 +30,7 @@ import (
)

var ErrDuplicated = errors.New("account is duplicated")
var ErrCanNotEdit = errors.New("account can not be edited")

//CreateAccount save 2 kv
//1. account info
Expand Down Expand Up @@ -86,3 +87,30 @@ func AccountExist(ctx context.Context, name string) (bool, error) {
}
return exist, nil
}

//CreateAccount save 2 kv
//1. account info
func EditAccount(ctx context.Context, a *model.Account) error {
key := core.GenerateAccountKey(a.Name)
exist, err := kv.Exist(ctx, key)
if err != nil {
log.Errorf(err, "can not edit account info")
return err
}
if !exist {
return ErrCanNotEdit
}

value, err := json.Marshal(a)
if err != nil {
log.Errorf(err, "account info is invalid")
return err
}
err = kv.PutBytes(ctx, key, value)
if err != nil {
log.Errorf(err, "can not edit account info")
return err
}

return nil
}
53 changes: 0 additions & 53 deletions server/service/rbac/dao/secret_dao.go

This file was deleted.

36 changes: 0 additions & 36 deletions server/service/rbac/dao/secret_dao_test.go

This file was deleted.

0 comments on commit 964cb02

Please sign in to comment.