470 // Check for Auth
471 if ok := srv.checkAuthorization(c); !ok {
472 c.authViolation()
473 return ErrAuthorization
474 }
这里会调用:
82 // checkAuthorization will check authorization based on client type and
83 // return boolean indicating if client is authorized.
84 func (s *Server) checkAuthorization(c *client) bool {
85 switch c.typ {
86 case CLIENT:
87 return s.isClientAuthorized(c)
然后会注册这个客户端到订阅的列表中:
95 // isClientAuthorized will check the client against the proper authorization method and data.
96 // This could be token or username/password based.
97 func (s *Server) isClientAuthorized(c *client) bool {
98 // Snapshot server options.
99 opts := s.getOpts()
100
101 // Check multiple users first, then token, then single user/pass.
102 if s.users != nil {
103 user, ok := s.users[c.opts.Username]
104 if !ok {
105 return false
106 }
107 ok = comparePasswords(user.Password, c.opts.Password)
108 // If we are authorized, register the user which will properly setup any permissions
109 // for pub/sub authorizations.
110 if ok {
111 c.RegisterUser(user)
插入过程会先构建一个subscription对象:
222 // RegisterUser allows auth to call back into a new client
223 // with the authenticated user. This is used to map any permissions
224 // into the client.
225 func (c *client) RegisterUser(user *User) {
...
243
244 // Loop over publish permissions
245 for _, pubSubject := range user.Permissions.Publish {
246 sub := &subscription{subject: []byte(pubSubject)}
247 c.perms.pub.Insert(sub)
248 }
249
250 // Loop over subscribe permissions
251 for _, subSubject := range user.Permissions.Subscribe {
252 sub := &subscription{subject: []byte(subSubject)}
253 c.perms.sub.Insert(sub)
254 }
其中permission的定义为:
120 type permissions struct {
121 sub *Sublist
122 pub *Sublist
123 pcache map[string]bool
124 }
实际上就是一个保持了订阅主题和发布主题的列表。
然后在订阅处理中检查权限,判断客户端是否可以进行订阅操作:
782 // Check permissions if applicable.
783 if !c.canSubscribe(sub.subject) {
784 c.mu.Unlock()
785 c.sendErr(fmt.Sprintf("Permissions Violation for Subscription to %q", sub.subject))
786 c.Errorf("Subscription Violation - User %q, Subject %q, SID %s",
787 c.opts.Username, sub.subject, sub.sid)
788 return nil
789 }
791 // We can have two SUB protocols coming from a route due to some
792 // race conditions. We should make sure that we process only one.
793 sid := string(sub.sid)
794 if c.subs[sid] == nil {
795 c.subs[sid] = sub
只对第一个进行处理,并将其存入client里面的保存这个客户端订阅的字典中:
87 type client struct {
101 subs map[string]*subscription