func (sm *DefaultSecurityManager) Login(subject Subject, token authc.AuthenticationToken) error { d, ok := subject.(*Delegator) if !ok || d.mgr != sm { return errors.New("The subject must have been created by this SecurityManager!") } sm.logf("Login attempt by %s", token.Principal()) ai, err := sm.Authenticate(token) if err == nil { d.principals = ai.Principals() d.authenticated = true sm.logf("Login successful, got principal list: %v", subject) if sm.sessionManager != nil { d.store() } return nil } return err }
func (r *CachingRealm) AuthenticationInfo(token authc.AuthenticationToken) (authc.AuthenticationInfo, error) { cachekey, ok := token.Principal().(string) var info authc.AuthenticationInfo var err error if ok { i := r.cache.Get(cachekey) if i != nil { info = i.(authc.AuthenticationInfo) return info, nil } } info, err = r.realm.AuthenticationInfo(token) if err != nil { // TODO: Should also cache the negative result. return nil, err } if ok { r.cache.Set(cachekey, cache.Item{Maxage: r.AuthenticationAge, Value: info}) } return info, nil }
func (cm *PlainText) Match(token authc.AuthenticationToken, info authc.AuthenticationInfo) bool { var givenPwd []byte // FIXME: Don't ignore errors switch token.Credentials().(type) { case string: givenPwd = []byte(token.Credentials().(string)) case []byte: givenPwd = token.Credentials().([]byte) } storedPwd, _ := info.Credentials().(string) return bytes.Equal(givenPwd, []byte(storedPwd)) }
func (cm *Hashed) Match(token authc.AuthenticationToken, info authc.AuthenticationInfo) bool { hash := getHash(cm.hashAlgorithm) var creds []byte creds = token.Credentials().([]byte) if salt, ok := info.(authc.SaltedAuthenticationInfo); ok { hash.Write(salt.CredentialsSalt()) } var i int32 for i = 0; i < cm.hashIterations; i++ { io.Copy(hash, bytes.NewReader(creds)) } final := hash.Sum(nil) return bytes.Equal(final, info.Credentials().([]byte)) }
func (sm *DefaultSecurityManager) Authenticate(token authc.AuthenticationToken) (authc.AuthenticationInfo, error) { if len(sm.realms) == 0 { return nil, errors.New("The SecurityManager has no Realms and is not configured properly") } sm.logf("Authenticating %s", token.Principal()) for _, r := range sm.realms { if r.Supports(token) { sm.logf("Authenticating '%s' against realm '%v'", token.Principal(), r.Name()) ai, err := r.AuthenticationInfo(token) // TODO: This is basically the "first realm that supports this token fails" -method // It should really be a pluggable authenticator if err != nil { sm.logf("Login failed for %s due to %s", token.Principal(), err.Error()) return nil, err } // Perform credentials matching ar, ok := r.(realm.AuthenticatingRealm) if !ok { return nil, errors.New("This realm does not support authenticating") } if match := ar.CredentialsMatcher().Match(token, ai); match { return ai, nil } return nil, errors.New("Incorrect credentials given") } } return nil, errors.New("Unknown user account") // FIXME: Return proper error type }
func (r *MockRealm) AuthenticationInfo(token authc.AuthenticationToken) (authc.AuthenticationInfo, error) { sa := authc.NewAccount(token.Principal(), token.Credentials(), r.Name()) r.authinfocalled++ return sa, nil }