Merge pull request #1226 from nats-io/bearer-token

[ADDED] Support for JWT BearerToken
This commit is contained in:
Ivan Kozlovic
2020-05-20 14:53:13 -06:00
committed by GitHub
2 changed files with 70 additions and 20 deletions

View File

@@ -427,28 +427,32 @@ func (s *Server) processClientOrLeafAuthentication(c *client) bool {
c.Debugf("Account JWT has expired")
return false
}
// Verify the signature against the nonce.
if c.opts.Sig == "" {
c.Debugf("Signature missing")
return false
}
sig, err := base64.RawURLEncoding.DecodeString(c.opts.Sig)
if err != nil {
// Allow fallback to normal base64.
sig, err = base64.StdEncoding.DecodeString(c.opts.Sig)
if err != nil {
c.Debugf("Signature not valid base64")
// skip validation of nonce when presented with a bearer token
// FIXME: if BearerToken is only for WSS, need check for server with that port enabled
if !juc.BearerToken {
// Verify the signature against the nonce.
if c.opts.Sig == "" {
c.Debugf("Signature missing")
return false
}
sig, err := base64.RawURLEncoding.DecodeString(c.opts.Sig)
if err != nil {
// Allow fallback to normal base64.
sig, err = base64.StdEncoding.DecodeString(c.opts.Sig)
if err != nil {
c.Debugf("Signature not valid base64")
return false
}
}
pub, err := nkeys.FromPublicKey(juc.Subject)
if err != nil {
c.Debugf("User nkey not valid: %v", err)
return false
}
if err := pub.Verify(c.nonce, sig); err != nil {
c.Debugf("Signature not verified")
return false
}
}
pub, err := nkeys.FromPublicKey(juc.Subject)
if err != nil {
c.Debugf("User nkey not valid: %v", err)
return false
}
if err := pub.Verify(c.nonce, sig); err != nil {
c.Debugf("Signature not verified")
return false
}
if acc.checkUserRevoked(juc.Subject) {
c.Debugf("User authentication revoked")

View File

@@ -2449,3 +2449,49 @@ func TestJWTAccountLimitsMaxConnsAfterExpired(t *testing.T) {
return nil
})
}
func TestBearerToken(t *testing.T) {
okp, _ := nkeys.FromSeed(oSeed)
akp, _ := nkeys.CreateAccount()
apub, _ := akp.PublicKey()
nac := jwt.NewAccountClaims(apub)
ajwt, err := nac.Encode(okp)
if err != nil {
t.Fatalf("Error generating account JWT: %v", err)
}
nkp, _ := nkeys.CreateUser()
pub, _ := nkp.PublicKey()
nuc := newJWTTestUserClaims()
nuc.Subject = pub
// Set bearer token.
nuc.BearerToken = true
jwt, err := nuc.Encode(akp)
if err != nil {
t.Fatalf("Error generating user JWT: %v", err)
}
s := opTrustBasicSetup()
defer s.Shutdown()
buildMemAccResolver(s)
addAccountToMemResolver(s, apub, ajwt)
c, cr, _ := newClientForServer(s)
defer c.close()
// Skip nonce signature...
// PING needed to flush the +OK/-ERR to us.
cs := fmt.Sprintf("CONNECT {\"jwt\":%q,\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", jwt)
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
c.parse([]byte(cs))
wg.Done()
}()
l, _ := cr.ReadString('\n')
if !strings.HasPrefix(l, "+OK") {
t.Fatalf("Expected +OK, got %s", l)
}
wg.Wait()
}