Repository: jcmturner/gokrb5
Pull request #356 (2020-01-30 21:13:21)

revert v7 API breaking changes


Patch:
diff --git a/client/ASExchange.go b/client/ASExchange.go
index dc74a4d..9d1a2f3 100644
--- a/client/ASExchange.go
+++ b/client/ASExchange.go
@@ -97,7 +97,7 @@ func setPAData(cl *Client, krberr *messages.KRBError, ASReq *messages.ASReq) err
 			if err != nil {
 				return krberror.Errorf(err, krberror.EncryptingError, "error getting etype for pre-auth encryption")
 			}
-			key, _, err = cl.Key(et, 0, nil)
+			key, err = cl.Key(et, nil)
 			if err != nil {
 				return krberror.Errorf(err, krberror.EncryptingError, "error getting key from credentials")
 			}
@@ -108,7 +108,7 @@ func setPAData(cl *Client, krberr *messages.KRBError, ASReq *messages.ASReq) err
 				return krberror.Errorf(err, krberror.EncryptingError, "error getting etype for pre-auth encryption")
 			}
 			cl.settings.preAuthEType = et.GetETypeID() // Set the etype that has been defined for potential future use
-			key, _, err = cl.Key(et, 0, krberr)
+			key, err = cl.Key(et, krberr)
 			if err != nil {
 				return krberror.Errorf(err, krberror.EncryptingError, "error getting key from credentials")
 			}
diff --git a/client/client.go b/client/client.go
index b56b697..cc93174 100644
--- a/client/client.go
+++ b/client/client.go
@@ -27,9 +27,9 @@ type Client struct {
 	cache       *Cache
 }
 
-// NewWithPassword creates a new client from a password credential.
+// NewClientWithPassword creates a new client from a password credential.
 // Set the realm to empty string to use the default realm from config.
-func NewWithPassword(username, realm, password string, krb5conf *config.Config, settings ...func(*Settings)) *Client {
+func NewClientWithPassword(username, realm, password string, krb5conf *config.Config, settings ...func(*Settings)) *Client {
 	creds := credentials.New(username, realm)
 	return &Client{
 		Credentials: creds.WithPassword(password),
@@ -42,8 +42,8 @@ func NewWithPassword(username, realm, password string, krb5conf *config.Config,
 	}
 }
 
-// NewWithKeytab creates a new client from a keytab credential.
-func NewWithKeytab(username, realm string, kt *keytab.Keytab, krb5conf *config.Config, settings ...func(*Settings)) *Client {
+// NewClientWithKeytab creates a new client from a keytab credential.
+func NewClientWithKeytab(username, realm string, kt *keytab.Keytab, krb5conf *config.Config, settings ...func(*Settings)) *Client {
 	creds := credentials.New(username, realm)
 	return &Client{
 		Credentials: creds.WithKeytab(kt),
@@ -56,10 +56,10 @@ func NewWithKeytab(username, realm string, kt *keytab.Keytab, krb5conf *config.C
 	}
 }
 
-// NewFromCCache create a client from a populated client cache.
+// NewClientFromCCache create a client from a populated client cache.
 //
 // WARNING: A client created from CCache does not automatically renew TGTs and a failure will occur after the TGT expires.
-func NewFromCCache(c *credentials.CCache, krb5conf *config.Config, settings ...func(*Settings)) (*Client, error) {
+func NewClientFromCCache(c *credentials.CCache, krb5conf *config.Config, settings ...func(*Settings)) (*Client, error) {
 	cl := &Client{
 		Credentials: c.GetClientCredentials(),
 		Config:      krb5conf,
@@ -108,28 +108,28 @@ func NewFromCCache(c *credentials.CCache, krb5conf *config.Config, settings ...f
 	return cl, nil
 }
 
-// Key returns the client's encryption key for the specified encryption type and its kvno (kvno of zero will find latest).
+// Key returns the client's encryption key for the specified encryption type.
 // The key can be retrieved either from the keytab or generated from the client's password.
 // If the client has both a keytab and a password defined the keytab is favoured as the source for the key
 // A KRBError can be passed in the event the KDC returns one of type KDC_ERR_PREAUTH_REQUIRED and is required to derive
 // the key for pre-authentication from the client's password. If a KRBError is not available, pass nil to this argument.
-func (cl *Client) Key(etype etype.EType, kvno int, krberr *messages.KRBError) (types.EncryptionKey, int, error) {
+func (cl *Client) Key(etype etype.EType, krberr *messages.KRBError) (types.EncryptionKey, error) {
 	if cl.Credentials.HasKeytab() && etype != nil {
-		return cl.Credentials.Keytab().GetEncryptionKey(cl.Credentials.CName(), cl.Credentials.Domain(), kvno, etype.GetETypeID())
+		return cl.Credentials.Keytab().GetEncryptionKey(cl.Credentials.CName(), cl.Credentials.Domain(), 0, etype.GetETypeID())
 	} else if cl.Credentials.HasPassword() {
 		if krberr != nil && krberr.ErrorCode == errorcode.KDC_ERR_PREAUTH_REQUIRED {
 			var pas types.PADataSequence
 			err := pas.Unmarshal(krberr.EData)
 			if err != nil {
-				return types.EncryptionKey{}, 0, fmt.Errorf("could not get PAData from KRBError to generate key from password: %v", err)
+				return types.EncryptionKey{}, fmt.Errorf("could not get PAData from KRBError to generate key from password: %v", err)
 			}
 			key, _, err := crypto.GetKeyFromPassword(cl.Credentials.Password(), krberr.CName, krberr.CRealm, etype.GetETypeID(), pas)
-			return key, 0, err
+			return key, err
 		}
 		key, _, err := crypto.GetKeyFromPassword(cl.Credentials.Password(), cl.Credentials.CName(), cl.Credentials.Domain(), etype.GetETypeID(), types.PADataSequence{})
-		return key, 0, err
+		return key, err
 	}
-	return types.EncryptionKey{}, 0, errors.New("credential has neither keytab or password to generate key")
+	return types.EncryptionKey{}, errors.New("credential has neither keytab or password to generate key")
 }
 
 // IsConfigured indicates if the client has the values required set.
@@ -171,7 +171,7 @@ func (cl *Client) Login() error {
 			return krberror.Errorf(err, krberror.KRBMsgError, "no user credentials available and error getting any existing session")
 		}
 		if time.Now().UTC().After(endTime) {
-			return krberror.New(krberror.KRBMsgError, "cannot login, no user credentials available and no valid existing session")
+			return krberror.NewKrberror(krberror.KRBMsgError, "cannot login, no user credentials available and no valid existing session")
 		}
 		// no credentials but there is a session with tgt already
 		return nil
diff --git a/config/krb5conf.go b/config/krb5conf.go
index 619e9fb..8efe92d 100644
--- a/config/krb5conf.go
+++ b/config/krb5conf.go
@@ -32,8 +32,8 @@ type Config struct {
 // WeakETypeList is a list of encryption types that have been deemed weak.
 const WeakETypeList = "des-cbc-crc des-cbc-md4 des-cbc-md5 des-cbc-raw des3-cbc-raw des-hmac-sha1 arcfour-hmac-exp rc4-hmac-exp arcfour-hmac-md5-exp des"
 
-// New creates a new config struct instance.
-func New() *Config {
+// NewConfig creates a new config struct instance.
+func NewConfig() *Config {
 	d := make(DomainRealm)
 	return &Config{
 		LibDefaults: newLibDefaults(),
@@ -523,24 +523,24 @@ func Load(cfgPath string) (*Config, error) {
 	}
 	defer fh.Close()
 	scanner := bufio.NewScanner(fh)
-	return NewFromScanner(scanner)
+	return NewConfigFromScanner(scanner)
 }
 
-// NewFromString creates a new Config struct from a string.
-func NewFromString(s string) (*Config, error) {
+// NewConfigFromString creates a new Config struct from a string.
+func NewConfigFromString(s string) (*Config, error) {
 	reader := strings.NewReader(s)
-	return NewFromReader(reader)
+	return NewConfigFromReader(reader)
 }
 
-// NewFromReader creates a new Config struct from an io.Reader.
-func NewFromReader(r io.Reader) (*Config, error) {
+// NewConfigFromReader creates a new Config struct from an io.Reader.
+func NewConfigFromReader(r io.Reader) (*Config, error) {
 	scanner := bufio.NewScanner(r)
-	return NewFromScanner(scanner)
+	return NewConfigFromScanner(scanner)
 }
 
-// NewFromScanner creates a new Config struct from a bufio.Scanner.
-func NewFromScanner(scanner *bufio.Scanner) (*Config, error) {
-	c := New()
+// NewConfigFromScanner creates a new Config struct from a bufio.Scanner.
+func NewConfigFromScanner(scanner *bufio.Scanner) (*Config, error) {
+	c := NewConfig()
 	var e error
 	sections := make(map[int]string)
 	var sectionLineNum []int
diff --git a/credentials/credentials.go b/credentials/credentials.go
index 59eb08f..beec066 100644
--- a/credentials/credentials.go
+++ b/credentials/credentials.go
@@ -2,8 +2,6 @@
 package credentials
 
 import (
-	"bytes"
-	"encoding/gob"
 	"time"
 
 	"github.com/hashicorp/go-uuid"
@@ -21,14 +19,15 @@ const (
 // Contains either a keytab, password or both.
 // Keytabs are used over passwords if both are defined.
 type Credentials struct {
-	username        string
-	displayName     string
-	realm           string
-	cname           types.PrincipalName
-	keytab          *keytab.Keytab
-	password        string
-	attributes      map[string]interface{}
-	validUntil      time.Time
+	username    string
+	displayName string
+	realm       string
+	cname       types.PrincipalName
+	keytab      *keytab.Keytab
+	password    string
+	attributes  map[string]interface{}
+	validUntil  time.Time
+
 	authenticated   bool
 	human           bool
 	authTime        time.Time
@@ -36,24 +35,6 @@ type Credentials struct {
 	sessionID       string
 }
 
-// marshalCredentials is used to enable marshaling and unmarshaling of credentials
-// without having exported fields on the Credentials struct
-type marshalCredentials struct {
-	Username        string
-	DisplayName     string
-	Realm           string
-	CName           types.PrincipalName
-	Keytab          *keytab.Keytab
-	Password        string
-	Attributes      map[string]interface{}
-	ValidUntil      time.Time
-	Authenticated   bool
-	Human           bool
-	AuthTime        time.Time
-	GroupMembership map[string]bool
-	SessionID       string
-}
-
 // ADCredentials contains information obtained from the PAC.
 type ADCredentials struct {
 	EffectiveName       string
@@ -90,9 +71,21 @@ func New(username string, realm string) *Credentials {
 
 // NewFromPrincipalName creates a new Credentials instance with the user details provides as a PrincipalName type.
 func NewFromPrincipalName(cname types.PrincipalName, realm string) *Credentials {
-	c := New(cname.PrincipalNameString(), realm)
-	c.cname = cname
-	return c
+	uid, err := uuid.GenerateUUID()
+	if err != nil {
+		uid = "00unique-sess-ions-uuid-unavailable0"
+	}
+	return &Credentials{
+		username:        cname.PrincipalNameString(),
+		displayName:     cname.PrincipalNameString(),
+		realm:           realm,
+		cname:           cname,
+		keytab:          keytab.New(),
+		attributes:      make(map[string]interface{}),
+		groupMembership: make(map[string]bool),
+		sessionID:       uid,
+		human:           true,
+	}
 }
 
 // WithKeytab sets the Keytab in the Credentials struct.
@@ -154,14 +147,6 @@ func (c *Credentials) SetADCredentials(a ADCredentials) {
 	}
 }
 
-// GetADCredentials returns ADCredentials attributes sorted in the credential
-func (c *Credentials) GetADCredentials() ADCredentials {
-	if a, ok := c.attributes[AttributeKeyADCredentials].(ADCredentials); ok {
-		return a
-	}
-	return ADCredentials{}
-}
-
 // Methods to implement goidentity.Identity interface
 
 // UserName returns the credential's username.
@@ -327,58 +312,3 @@ func (c *Credentials) SetAttributes(a map[string]interface{}) {
 func (c *Credentials) RemoveAttribute(k string) {
 	delete(c.attributes, k)
 }
-
-// Marshal the Credentials into a byte slice
-func (c *Credentials) Marshal() ([]byte, error) {
-	gob.Register(map[string]interface{}{})
-	gob.Register(ADCredentials{})
-	buf := new(bytes.Buffer)
-	enc := gob.NewEncoder(buf)
-	mc := marshalCredentials{
-		Username:        c.username,
-		DisplayName:     c.displayName,
-		Realm:           c.realm,
-		CName:           c.cname,
-		Keytab:          c.keytab,
-		Password:        c.password,
-		Attributes:      c.attributes,
-		ValidUntil:      c.validUntil,
-		Authenticated:   c.authenticated,
-		Human:           c.human,
-		AuthTime:        c.authTime,
-		GroupMembership: c.groupMembership,
-		SessionID:       c.sessionID,
-	}
-	err := enc.Encode(&mc)
-	if err != nil {
-		return []byte{}, err
-	}
-	return buf.Bytes(), nil
-}
-
-// Unmarshal a byte slice into Credentials
-func (c *Credentials) Unmarshal(b []byte) error {
-	gob.Register(map[string]interface{}{})
-	gob.Register(ADCredentials{})
-	mc := new(marshalCredentials)
-	buf := bytes.NewBuffer(b)
-	dec := gob.NewDecoder(buf)
-	err := dec.Decode(mc)
-	if err != nil {
-		return err
-	}
-	c.username = mc.Username
-	c.displayName = mc.DisplayName
-	c.realm = mc.Realm
-	c.cname = mc.CName
-	c.keytab = mc.Keytab
-	c.password = mc.Password
-	c.attributes = mc.Attributes
-	c.validUntil = mc.ValidUntil
-	c.authenticated = mc.Authenticated
-	c.human = mc.Human
-	c.authTime = mc.AuthTime
-	c.groupMembership = mc.GroupMembership
-	c.sessionID = mc.SessionID
-	return nil
-}
diff --git a/examples/example-AD.go b/examples/example-AD.go
index c0e0a6b..0e830fb 100644
--- a/examples/example-AD.go
+++ b/examples/example-AD.go
@@ -4,9 +4,8 @@ package main
 
 import (
 	"encoding/hex"
-	"encoding/json"
 	"fmt"
-	"gopkg.in/jcmturner/goidentity.v5"
+	"gopkg.in/jcmturner/goidentity.v3"
 	"gopkg.in/jcmturner/gokrb5.v7/client"
 	"gopkg.in/jcmturner/gokrb5.v7/config"
 	"gopkg.in/jcmturner/gokrb5.v7/credentials"
@@ -28,15 +27,15 @@ func main() {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_USERKRB5_AD_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
-	cl := client.NewWithKeytab("testuser1", "USER.GOKRB5", kt, c, client.DisablePAFXFAST(true))
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
+	cl := client.NewClientWithKeytab("testuser1", "USER.GOKRB5", kt, c, client.DisablePAFXFAST(true))
 	httpRequest(s.URL, cl)
 
 	b, _ = hex.DecodeString(testdata.TESTUSER2_USERKRB5_AD_KEYTAB)
 	kt = keytab.New()
 	kt.Unmarshal(b)
-	c, _ = config.NewFromString(testdata.TEST_KRB5CONF)
-	cl = client.NewWithKeytab("testuser2", "USER.GOKRB5", kt, c, client.DisablePAFXFAST(true))
+	c, _ = config.NewConfigFromString(testdata.TEST_KRB5CONF)
+	cl = client.NewClientWithKeytab("testuser2", "USER.GOKRB5", kt, c, client.DisablePAFXFAST(true))
 	httpRequest(s.URL, cl)
 
 	//httpRequest("http://host.test.gokrb5/index.html")
@@ -74,20 +73,18 @@ func httpServer() *httptest.Server {
 }
 
 func testAppHandler(w http.ResponseWriter, r *http.Request) {
-	creds := goidentity.FromHTTPRequestContext(r)
+	ctx := r.Context()
 	fmt.Fprint(w, "<html>\n<p><h1>TEST.GOKRB5 Handler</h1></p>\n")
-	if creds != nil && creds.Authenticated() {
-		fmt.Fprintf(w, "<ul><li>Authenticed user: %s</li>\n", creds.UserName())
-		fmt.Fprintf(w, "<li>User's realm: %s</li>\n", creds.Domain())
-		fmt.Fprint(w, "<li>Authz Attributes (Group Memberships):</li><ul>\n")
-		for _, s := range creds.AuthzAttributes() {
-			fmt.Fprintf(w, "<li>%v</li>\n", s)
-		}
-		fmt.Fprint(w, "</ul>\n")
-		if ADCredsJSON, ok := creds.Attributes()[credentials.AttributeKeyADCredentials]; ok {
-			ADCreds := new(credentials.ADCredentials)
-			err := json.Unmarshal([]byte(ADCredsJSON), ADCreds)
-			if err == nil {
+	if validuser, ok := ctx.Value(spnego.CTXKeyAuthenticated).(bool); ok && validuser {
+		if creds, ok := ctx.Value(spnego.CTXKeyCredentials).(goidentity.Identity); ok {
+			fmt.Fprintf(w, "<ul><li>Authenticed user: %s</li>\n", creds.UserName())
+			fmt.Fprintf(w, "<li>User's realm: %s</li>\n", creds.Domain())
+			fmt.Fprint(w, "<li>Authz Attributes (Group Memberships):</li><ul>\n")
+			for _, s := range creds.AuthzAttributes() {
+				fmt.Fprintf(w, "<li>%v</li>\n", s)
+			}
+			fmt.Fprint(w, "</ul>\n")
+			if ADCreds, ok := creds.Attributes()[credentials.AttributeKeyADCredentials].(credentials.ADCredentials); ok {
 				// Now access the fields of the ADCredentials struct. For example:
 				fmt.Fprintf(w, "<li>EffectiveName: %v</li>\n", ADCreds.EffectiveName)
 				fmt.Fprintf(w, "<li>FullName: %v</li>\n", ADCreds.FullName)
@@ -101,8 +98,9 @@ func testAppHandler(w http.ResponseWriter, r *http.Request) {
 				fmt.Fprintf(w, "<li>LogonDomainName: %v</li>\n", ADCreds.LogonDomainName)
 				fmt.Fprintf(w, "<li>LogonDomainID: %v</li>\n", ADCreds.LogonDomainID)
 			}
+			fmt.Fprint(w, "</ul>")
 		}
-		fmt.Fprint(w, "</ul>")
+
 	} else {
 		w.WriteHeader(http.StatusUnauthorized)
 		fmt.Fprint(w, "Authentication failed")
diff --git a/examples/example.go b/examples/example.go
index c015a01..8971c3a 100644
--- a/examples/example.go
+++ b/examples/example.go
@@ -1,6 +1,6 @@
-// Package examples provides simple examples of gokrb5 use.
 // +build examples
 
+// Package examples provides simple examples of gokrb5 use.
 package main
 
 import (
@@ -12,7 +12,7 @@ import (
 	"net/http/httptest"
 	"os"
 
-	"gopkg.in/jcmturner/goidentity.v5"
+	"gopkg.in/jcmturner/goidentity.v3"
 	"gopkg.in/jcmturner/gokrb5.v7/client"
 	"gopkg.in/jcmturner/gokrb5.v7/config"
 	"gopkg.in/jcmturner/gokrb5.v7/keytab"
@@ -28,17 +28,17 @@ func main() {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	c.LibDefaults.NoAddresses = true
-	cl := client.NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+	cl := client.NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 	httpRequest(s.URL, cl)
 
 	b, _ = hex.DecodeString(testdata.TESTUSER2_KEYTAB)
 	kt = keytab.New()
 	kt.Unmarshal(b)
-	c, _ = config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ = config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	c.LibDefaults.NoAddresses = true
-	cl = client.NewWithKeytab("testuser2", "TEST.GOKRB5", kt, c)
+	cl = client.NewClientWithKeytab("testuser2", "TEST.GOKRB5", kt, c)
 	httpRequest(s.URL, cl)
 }
 
@@ -74,11 +74,14 @@ func httpServer() *httptest.Server {
 }
 
 func testAppHandler(w http.ResponseWriter, r *http.Request) {
-	creds := goidentity.FromHTTPRequestContext(r)
+	ctx := r.Context()
 	fmt.Fprint(w, "<html>\n<p><h1>TEST.GOKRB5 Handler</h1></p>\n")
-	if creds != nil && creds.Authenticated() {
-		fmt.Fprintf(w, "<ul><li>Authenticed user: %s</li>\n", creds.UserName())
-		fmt.Fprintf(w, "<li>User's realm: %s</li></ul>\n", creds.Domain())
+	if validuser, ok := ctx.Value(spnego.CTXKeyAuthenticated).(bool); ok && validuser {
+		if creds, ok := ctx.Value(spnego.CTXKeyCredentials).(goidentity.Identity); ok {
+			fmt.Fprintf(w, "<ul><li>Authenticed user: %s</li>\n", creds.UserName())
+			fmt.Fprintf(w, "<li>User's realm: %s</li></ul>\n", creds.Domain())
+		}
+
 	} else {
 		w.WriteHeader(http.StatusUnauthorized)
 		fmt.Fprint(w, "Authentication failed")
diff --git a/examples/httpClient.go b/examples/httpClient.go
index f6d72cb..a48fe95 100644
--- a/examples/httpClient.go
+++ b/examples/httpClient.go
@@ -54,7 +54,7 @@ func main() {
 	}
 
 	// Load the client krb5 config
-	conf, err := config.NewFromString(kRB5CONF)
+	conf, err := config.NewConfigFromString(kRB5CONF)
 	if err != nil {
 		l.Fatalf("could not load krb5.conf: %v", err)
 	}
@@ -64,7 +64,7 @@ func main() {
 	}
 
 	// Create the client with the keytab
-	cl := client.NewWithKeytab("testuser2", "TEST.GOKRB5", kt, conf, client.Logger(l), client.DisablePAFXFAST(true))
+	cl := client.NewClientWithKeytab("testuser2", "TEST.GOKRB5", kt, conf, client.Logger(l), client.DisablePAFXFAST(true))
 
 	// Log in the client
 	err = cl.Login()
diff --git a/examples/httpServer.go b/examples/httpServer.go
index ad1e63b..c7cffc1 100644
--- a/examples/httpServer.go
+++ b/examples/httpServer.go
@@ -9,9 +9,7 @@ import (
 	"net/http"
 	"os"
 
-	"github.com/gorilla/sessions"
-	"github.com/pkg/errors"
-	"gopkg.in/jcmturner/goidentity.v5"
+	goidentity "gopkg.in/jcmturner/goidentity.v3"
 	"gopkg.in/jcmturner/gokrb5.v7/keytab"
 	"gopkg.in/jcmturner/gokrb5.v7/service"
 	"gopkg.in/jcmturner/gokrb5.v7/spnego"
@@ -37,7 +35,7 @@ func main() {
 
 	// Set up handler mappings wrapping in the SPNEGOKRB5Authenticate handler wrapper
 	mux := http.NewServeMux()
-	mux.Handle("/", spnego.SPNEGOKRB5Authenticate(th, kt, service.Logger(l), service.SessionManager(NewSessionMgr("gokrb5"))))
+	mux.Handle("/", spnego.SPNEGOKRB5Authenticate(th, kt, service.Logger(l)))
 
 	// Start up the web server
 	log.Fatal(http.ListenAndServe(port, mux))
@@ -46,7 +44,8 @@ func main() {
 // Simple application specific handler
 func testAppHandler(w http.ResponseWriter, r *http.Request) {
 	w.WriteHeader(http.StatusOK)
-	creds := goidentity.FromHTTPRequestContext(r)
+	ctx := r.Context()
+	creds := ctx.Value(spnego.CTXKeyCredentials).(goidentity.Identity)
 	fmt.Fprintf(w,
 		`<html>
 <h1>GOKRB5 Handler</h1>
@@ -64,42 +63,3 @@ func testAppHandler(w http.ResponseWriter, r *http.Request) {
 	)
 	return
 }
-
-type SessionMgr struct {
-	skey       []byte
-	store      sessions.Store
-	cookieName string
-}
-
-func NewSessionMgr(cookieName string) SessionMgr {
-	skey := []byte("thisistestsecret") // Best practice is to load this key from a secure location.
-	return SessionMgr{
-		skey:       skey,
-		store:      sessions.NewCookieStore(skey),
-		cookieName: cookieName,
-	}
-}
-
-func (smgr SessionMgr) Get(r *http.Request, k string) ([]byte, error) {
-	s, err := smgr.store.Get(r, smgr.cookieName)
-	if err != nil {
-		return nil, err
-	}
-	if s == nil {
-		return nil, errors.New("nil session")
-	}
-	b, ok := s.Values[k].([]byte)
-	if !ok {
-		return nil, fmt.Errorf("could not get bytes held in session at %s", k)
-	}
-	return b, nil
-}
-
-func (smgr SessionMgr) New(w http.ResponseWriter, r *http.Request, k string, v []byte) error {
-	s, err := smgr.store.New(r, smgr.cookieName)
-	if err != nil {
-		return fmt.Errorf("could not get new session from session manager: %v", err)
-	}
-	s.Values[k] = v
-	return s.Save(r, w)
-}
diff --git a/examples/longRunningClient.go b/examples/longRunningClient.go
index 9b72e10..084906e 100644
--- a/examples/longRunningClient.go
+++ b/examples/longRunningClient.go
@@ -1,5 +1,3 @@
-// +build examples
-
 package main
 
 import (
@@ -50,7 +48,7 @@ func main() {
 	}
 
 	// Load the client krb5 config
-	conf, err := config.NewFromString(kRB5CONF)
+	conf, err := config.NewConfigFromString(kRB5CONF)
 	if err != nil {
 		l.Fatalf("could not load krb5.conf: %v", err)
 	}
@@ -60,7 +58,7 @@ func main() {
 	}
 
 	// Create the client with the keytab
-	cl := client.NewWithKeytab("testuser2", "TEST.GOKRB5", kt, conf, client.Logger(l), client.DisablePAFXFAST(true))
+	cl := client.NewClientWithKeytab("testuser2", "TEST.GOKRB5", kt, conf, client.Logger(l), client.DisablePAFXFAST(true))
 
 	// Log in the client
 	err = cl.Login()
diff --git a/gssapi/gssapi.go b/gssapi/gssapi.go
index 8082231..47754d7 100644
--- a/gssapi/gssapi.go
+++ b/gssapi/gssapi.go
@@ -14,7 +14,6 @@ const (
 	OIDKRB5         OIDName = "KRB5"         // MechType OID for Kerberos 5
 	OIDMSLegacyKRB5 OIDName = "MSLegacyKRB5" // MechType OID for Kerberos 5
 	OIDSPNEGO       OIDName = "SPNEGO"
-	OIDGSSIAKerb    OIDName = "GSSIAKerb" // Indicates the client cannot get a service ticket and asks the server to serve as an intermediate to the target KDC. http://k5wiki.kerberos.org/wiki/Projects/IAKERB#IAKERB_mech
 )
 
 // GSS-API status values
@@ -118,7 +117,7 @@ type Mechanism interface {
 type OIDName string
 
 // OID returns the OID for the provided OID name.
-func (o OIDName) OID() asn1.ObjectIdentifier {
+func OID(o OIDName) asn1.ObjectIdentifier {
 	switch o {
 	case OIDSPNEGO:
 		return asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 2}
@@ -126,8 +125,6 @@ func (o OIDName) OID() asn1.ObjectIdentifier {
 		return asn1.ObjectIdentifier{1, 2, 840, 113554, 1, 2, 2}
 	case OIDMSLegacyKRB5:
 		return asn1.ObjectIdentifier{1, 2, 840, 48018, 1, 2, 2}
-	case OIDGSSIAKerb:
-		return asn1.ObjectIdentifier{1, 3, 6, 1, 5, 2, 5}
 	}
 	return asn1.ObjectIdentifier{}
 }
diff --git a/keytab/keytab.go b/keytab/keytab.go
index 6afeffd..22c0204 100644
--- a/keytab/keytab.go
+++ b/keytab/keytab.go
@@ -51,8 +51,8 @@ func New() *Keytab {
 }
 
 // GetEncryptionKey returns the EncryptionKey from the Keytab for the newest entry with the required kvno, etype and matching principal.
-// If the kvno is zero then the latest kvno will be returned. The kvno is also returned for
-func (kt *Keytab) GetEncryptionKey(princName types.PrincipalName, realm string, kvno int, etype int32) (types.EncryptionKey, int, error) {
+func (kt *Keytab) GetEncryptionKey(princName types.PrincipalName, realm string, kvno int, etype int32) (types.EncryptionKey, error) {
+	//TODO (theme: KVNO from keytab) this function should return the kvno too
 	var key types.EncryptionKey
 	var t time.Time
 	for _, k := range kt.Entries {
@@ -69,19 +69,18 @@ func (kt *Keytab) GetEncryptionKey(princName types.PrincipalName, realm string,
 			}
 			if p {
 				key = k.Key
-				kvno = int(k.KVNO)
 				t = k.Timestamp
 			}
 		}
 	}
 	if len(key.KeyValue) < 1 {
-		return key, 0, fmt.Errorf("matching key not found in keytab. Looking for %v realm: %v kvno: %v etype: %v", princName.NameString, realm, kvno, etype)
+		return key, fmt.Errorf("matching key not found in keytab. Looking for %v realm: %v kvno: %v etype: %v", princName.NameString, realm, kvno, etype)
 	}
-	return key, kvno, nil
+	return key, nil
 }
 
 // Create a new Keytab entry.
-func newEntry() entry {
+func newKeytabEntry() entry {
 	var b []byte
 	return entry{
 		Principal: newPrincipal(),
@@ -189,7 +188,7 @@ func (kt *Keytab) Unmarshal(b []byte) error {
 			}
 			eb := b[n : n+int(l)]
 			n = n + int(l)
-			ke := newEntry()
+			ke := newKeytabEntry()
 			// p keeps track as to where we are in the byte stream
 			var p int
 			var err error
diff --git a/krberror/error.go b/krberror/error.go
index 01c6d99..d591bde 100644
--- a/krberror/error.go
+++ b/krberror/error.go
@@ -35,8 +35,8 @@ func (e *Krberror) Add(et string, s string) {
 	e.EText = append([]string{fmt.Sprintf("%s: %s", et, s)}, e.EText...)
 }
 
-// New creates a new instance of Krberror.
-func New(et, s string) Krberror {
+// NewKrberror creates a new instance of Krberror.
+func NewKrberror(et, s string) Krberror {
 	return Krberror{
 		RootCause: et,
 		EText:     []string{s},
diff --git a/messages/KDCRep.go b/messages/KDCRep.go
index f160ab3..76c89c3 100644
--- a/messages/KDCRep.go
+++ b/messages/KDCRep.go
@@ -154,7 +154,7 @@ func (k *ASRep) DecryptEncPart(c *credentials.Credentials) (types.EncryptionKey,
 	var key types.EncryptionKey
 	var err error
 	if c.HasKeytab() {
-		key, _, err = c.Keytab().GetEncryptionKey(k.CName, k.CRealm, k.EncPart.KVNO, k.EncPart.EType)
+		key, err = c.Keytab().GetEncryptionKey(k.CName, k.CRealm, k.EncPart.KVNO, k.EncPart.EType)
 		if err != nil {
 			return key, krberror.Errorf(err, krberror.DecryptingError, "error decrypting AS_REP encrypted part")
 		}
diff --git a/messages/Ticket.go b/messages/Ticket.go
index f618149..49664b8 100644
--- a/messages/Ticket.go
+++ b/messages/Ticket.go
@@ -83,7 +83,7 @@ func NewTicket(cname types.PrincipalName, crealm string, sname types.PrincipalNa
 		return Ticket{}, types.EncryptionKey{}, krberror.Errorf(err, krberror.EncodingError, "error marshalling ticket encpart")
 	}
 	b = asn1tools.AddASNAppTag(b, asnAppTag.EncTicketPart)
-	skey, _, err := sktab.GetEncryptionKey(sname, srealm, kvno, eTypeID)
+	skey, err := sktab.GetEncryptionKey(sname, srealm, kvno, eTypeID)
 	if err != nil {
 		return Ticket{}, types.EncryptionKey{}, krberror.Errorf(err, krberror.EncryptingError, "error getting encryption key for new ticket")
 	}
@@ -193,7 +193,7 @@ func (t *Ticket) DecryptEncPart(keytab *keytab.Keytab, sname *types.PrincipalNam
 	if sname == nil {
 		sname = &t.SName
 	}
-	key, _, err := keytab.GetEncryptionKey(*sname, t.Realm, t.EncPart.KVNO, t.EncPart.EType)
+	key, err := keytab.GetEncryptionKey(*sname, t.Realm, t.EncPart.KVNO, t.EncPart.EType)
 	if err != nil {
 		return NewKRBError(t.SName, t.Realm, errorcode.KRB_AP_ERR_NOKEY, fmt.Sprintf("Could not get key from keytab: %v", err))
 	}
@@ -236,7 +236,7 @@ func (t *Ticket) GetPACType(keytab *keytab.Keytab, sname *types.PrincipalName, l
 				if sname == nil {
 					sname = &t.SName
 				}
-				key, _, err := keytab.GetEncryptionKey(*sname, t.Realm, t.EncPart.KVNO, t.EncPart.EType)
+				key, err := keytab.GetEncryptionKey(*sname, t.Realm, t.EncPart.KVNO, t.EncPart.EType)
 				if err != nil {
 					return isPAC, p, NewKRBError(t.SName, t.Realm, errorcode.KRB_AP_ERR_NOKEY, fmt.Sprintf("Could not get key from keytab: %v", err))
 				}
diff --git a/service/APExchange.go b/service/APExchange.go
index 0105e56..4126cfa 100644
--- a/service/APExchange.go
+++ b/service/APExchange.go
@@ -9,8 +9,9 @@ import (
 )
 
 // VerifyAPREQ verifies an AP_REQ sent to the service. Returns a boolean for if the AP_REQ is valid and the client's principal name and realm.
-func VerifyAPREQ(APReq *messages.APReq, s *Settings) (bool, *credentials.Credentials, error) {
+func VerifyAPREQ(APReq messages.APReq, s *Settings) (bool, *credentials.Credentials, error) {
 	var creds *credentials.Credentials
+
 	ok, err := APReq.Verify(s.Keytab, s.MaxClockSkew(), s.ClientAddress())
 	if err != nil || !ok {
 		return false, creds, err
diff --git a/service/authenticator.go b/service/authenticator.go
index 091ca72..d60d259 100644
--- a/service/authenticator.go
+++ b/service/authenticator.go
@@ -6,7 +6,7 @@ import (
 	"strings"
 	"time"
 
-	goidentity "gopkg.in/jcmturner/goidentity.v5"
+	goidentity "gopkg.in/jcmturner/goidentity.v3"
 	"gopkg.in/jcmturner/gokrb5.v7/client"
 	"gopkg.in/jcmturner/gokrb5.v7/config"
 	"gopkg.in/jcmturner/gokrb5.v7/credentials"
@@ -22,7 +22,7 @@ func NewKRB5BasicAuthenticator(headerVal string, krb5conf *config.Config, servic
 	}
 }
 
-// KRB5BasicAuthenticator implements gopkg.in/jcmturner/goidentity.v5.Authenticator interface.
+// KRB5BasicAuthenticator implements gopkg.in/jcmturner/goidentity.v3.Authenticator interface.
 // It takes username and password so can be used for basic authentication.
 type KRB5BasicAuthenticator struct {
 	BasicHeaderValue string
@@ -41,7 +41,7 @@ func (a KRB5BasicAuthenticator) Authenticate() (i goidentity.Identity, ok bool,
 		err = fmt.Errorf("could not parse basic authentication header: %v", err)
 		return
 	}
-	cl := client.NewWithPassword(a.username, a.realm, a.password, a.clientConfig)
+	cl := client.NewClientWithPassword(a.username, a.realm, a.password, a.clientConfig)
 	err = cl.Login()
 	if err != nil {
 		// Username and/or password could be wrong
diff --git a/service/settings.go b/service/settings.go
index 0896cfa..6e373ce 100644
--- a/service/settings.go
+++ b/service/settings.go
@@ -2,7 +2,6 @@ package service
 
 import (
 	"log"
-	"net/http"
 	"time"
 
 	"gopkg.in/jcmturner/gokrb5.v7/keytab"
@@ -19,7 +18,6 @@ type Settings struct {
 	cAddr              types.HostAddress
 	maxClockSkew       time.Duration
 	logger             *log.Logger
-	sessionMgr         SessionMgr
 }
 
 // NewSettings creates a new service Settings.
@@ -136,27 +134,3 @@ func SName(sname string) func(*Settings) {
 func (s *Settings) SName() string {
 	return s.sname
 }
-
-// SessionManager configures a session manager to establish sessions with clients to avoid excessive authentication challenges.
-//
-// s := NewSettings(kt, SessionManager(sm))
-func SessionManager(sm SessionMgr) func(*Settings) {
-	return func(s *Settings) {
-		s.sessionMgr = sm
-	}
-}
-
-// SessionManager returns any configured session manager.
-func (s *Settings) SessionManager() SessionMgr {
-	return s.sessionMgr
-}
-
-// SessionMgr must provide a ways to:
-//
-// - Create new sessions and in the process add a value to the session under the key provided.
-//
-// - Get an existing the value in the session under the key provided. Return nil bytes and/or error if there is no session.
-type SessionMgr interface {
-	New(w http.ResponseWriter, r *http.Request, k string, v []byte) error
-	Get(r *http.Request, k string) ([]byte, error)
-}
diff --git a/spnego/http.go b/spnego/http.go
index 20889c5..0cb2844 100644
--- a/spnego/http.go
+++ b/spnego/http.go
@@ -2,6 +2,7 @@ package spnego
 
 import (
 	"bytes"
+	"context"
 	"encoding/base64"
 	"errors"
 	"fmt"
@@ -13,9 +14,8 @@ import (
 	"net/url"
 	"strings"
 
-	"gopkg.in/jcmturner/goidentity.v5"
+	"gopkg.in/jcmturner/goidentity.v3"
 	"gopkg.in/jcmturner/gokrb5.v7/client"
-	"gopkg.in/jcmturner/gokrb5.v7/credentials"
 	"gopkg.in/jcmturner/gokrb5.v7/gssapi"
 	"gopkg.in/jcmturner/gokrb5.v7/keytab"
 	"gopkg.in/jcmturner/gokrb5.v7/krberror"
@@ -191,6 +191,8 @@ func SetSPNEGOHeader(cl *client.Client, r *http.Request, spn string) error {
 
 // Service side functionality //
 
+type ctxKey string
+
 const (
 	// spnegoNegTokenRespKRBAcceptCompleted - The response on successful authentication always has this header. Capturing as const so we don't have marshaling and encoding overhead.
 	spnegoNegTokenRespKRBAcceptCompleted = "Negotiate oRQwEqADCgEAoQsGCSqGSIb3EgECAg=="
@@ -198,10 +200,10 @@ const (
 	spnegoNegTokenRespReject = "Negotiate oQcwBaADCgEC"
 	// spnegoNegTokenRespIncompleteKRB5 - Response token specifying incomplete context and KRB5 as the supported mechtype.
 	spnegoNegTokenRespIncompleteKRB5 = "Negotiate oRQwEqADCgEBoQsGCSqGSIb3EgECAg=="
-	// sessionCredentials is the session value key holding the credentials jcmturner/goidentity/Identity object.
-	sessionCredentials = "github.com/jcmturner/gokrb5/sessionCredentials"
-	// ctxCredentials is the SPNEGO context key holding the credentials jcmturner/goidentity/Identity object.
-	ctxCredentials = "github.com/jcmturner/gokrb5/ctxCredentials"
+	// CTXKeyAuthenticated is the request context key holding a boolean indicating if the request has been authenticated.
+	CTXKeyAuthenticated ctxKey = "github.com/jcmturner/gokrb5/CTXKeyAuthenticated"
+	// CTXKeyCredentials is the request context key holding the credentials gopkg.in/jcmturner/goidentity.v2/Identity object.
+	CTXKeyCredentials ctxKey = "github.com/jcmturner/gokrb5/CTXKeyCredentials"
 	// HTTPHeaderAuthRequest is the header that will hold authn/z information.
 	HTTPHeaderAuthRequest = "Authorization"
 	// HTTPHeaderAuthResponse is the header that will hold SPNEGO data from the server.
@@ -215,6 +217,15 @@ const (
 // SPNEGOKRB5Authenticate is a Kerberos SPNEGO authentication HTTP handler wrapper.
 func SPNEGOKRB5Authenticate(inner http.Handler, kt *keytab.Keytab, settings ...func(*service.Settings)) http.Handler {
 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		// Get the auth header
+		s := strings.SplitN(r.Header.Get(HTTPHeaderAuthRequest), " ", 2)
+		if len(s) != 2 || s[0] != HTTPHeaderAuthResponseValueKey {
+			// No Authorization header set so return 401 with WWW-Authenticate Negotiate header
+			w.Header().Set(HTTPHeaderAuthResponse, HTTPHeaderAuthResponseValueKey)
+			http.Error(w, UnauthorizedMsg, http.StatusUnauthorized)
+			return
+		}
+
 		// Set up the SPNEGO GSS-API mechanism
 		var spnego *SPNEGO
 		h, err := types.GetHostAddress(r.RemoteAddr)
@@ -227,23 +238,21 @@ func SPNEGOKRB5Authenticate(inner http.Handler, kt *keytab.Keytab, settings ...f
 			spnego.Log("%s - SPNEGO could not parse client address: %v", r.RemoteAddr, err)
 		}
 
-		// Check if there is a session manager and if there is an already established session for this client
-		id, err := getSessionCredentials(spnego, r)
-		if err == nil && id.Authenticated() {
-			// There is an established session so bypass auth and serve
-			spnego.Log("%s - SPNEGO request served under session %s", r.RemoteAddr, id.SessionID())
-			inner.ServeHTTP(w, goidentity.AddToHTTPRequestContext(&id, r))
+		// Decode the header into an SPNEGO context token
+		b, err := base64.StdEncoding.DecodeString(s[1])
+		if err != nil {
+			spnegoNegotiateKRB5MechType(spnego, w, "%s - SPNEGO error in base64 decoding negotiation header: %v", r.RemoteAddr, err)
 			return
 		}
-
-		st, err := getAuthorizationNegotiationHeaderAsSPNEGOToken(spnego, r, w)
-		if st == nil || err != nil {
-			// response to client and logging handled in function above so just return
+		var st SPNEGOToken
+		err = st.Unmarshal(b)
+		if err != nil {
+			spnegoNegotiateKRB5MechType(spnego, w, "%s - SPNEGO error in unmarshaling SPNEGO token: %v", r.RemoteAddr, err)
 			return
 		}
 
 		// Validate the context token
-		authed, ctx, status := spnego.AcceptSecContext(st)
+		authed, ctx, status := spnego.AcceptSecContext(&st)
 		if status.Code != gssapi.StatusComplete && status.Code != gssapi.StatusContinueNeeded {
 			spnegoResponseReject(spnego, w, "%s - SPNEGO validation error: %v", r.RemoteAddr, status)
 			return
@@ -252,89 +261,20 @@ func SPNEGOKRB5Authenticate(inner http.Handler, kt *keytab.Keytab, settings ...f
 			spnegoNegotiateKRB5MechType(spnego, w, "%s - SPNEGO GSS-API continue needed", r.RemoteAddr)
 			return
 		}
-
 		if authed {
-			// Authentication successful; get user's credentials from the context
-			id := ctx.Value(ctxCredentials).(*credentials.Credentials)
-			// Create a new session if a session manager has been configured
-			err = newSession(spnego, r, w, id)
-			if err != nil {
-				return
-			}
+			id := ctx.Value(CTXKeyCredentials).(goidentity.Identity)
+			requestCtx := r.Context()
+			requestCtx = context.WithValue(requestCtx, CTXKeyCredentials, id)
+			requestCtx = context.WithValue(requestCtx, CTXKeyAuthenticated, ctx.Value(CTXKeyAuthenticated))
 			spnegoResponseAcceptCompleted(spnego, w, "%s %s@%s - SPNEGO authentication succeeded", r.RemoteAddr, id.UserName(), id.Domain())
-			// Add the identity to the context and serve the inner/wrapped handler
-			inner.ServeHTTP(w, goidentity.AddToHTTPRequestContext(id, r))
+			inner.ServeHTTP(w, r.WithContext(requestCtx))
+		} else {
+			spnegoResponseReject(spnego, w, "%s - SPNEGO Kerberos authentication failed", r.RemoteAddr)
 			return
 		}
-		// If we get to here we have not authenticationed so just reject
-		spnegoResponseReject(spnego, w, "%s - SPNEGO Kerberos authentication failed", r.RemoteAddr)
-		return
 	})
 }
 
-func getAuthorizationNegotiationHeaderAsSPNEGOToken(spnego *SPNEGO, r *http.Request, w http.ResponseWriter) (*SPNEGOToken, error) {
-	s := strings.SplitN(r.Header.Get(HTTPHeaderAuthRequest), " ", 2)
-	if len(s) != 2 || s[0] != HTTPHeaderAuthResponseValueKey {
-		// No Authorization header set so return 401 with WWW-Authenticate Negotiate header
-		w.Header().Set(HTTPHeaderAuthResponse, HTTPHeaderAuthResponseValueKey)
-		http.Error(w, UnauthorizedMsg, http.StatusUnauthorized)
-		return nil, errors.New("client did not provide a negotiation authorization header")
-	}
-
-	// Decode the header into an SPNEGO context token
-	b, err := base64.StdEncoding.DecodeString(s[1])
-	if err != nil {
-		err = fmt.Errorf("error in base64 decoding negotiation header: %v", err)
-		spnegoNegotiateKRB5MechType(spnego, w, "%s - SPNEGO %v", r.RemoteAddr, err)
-		return nil, err
-	}
-	var st SPNEGOToken
-	err = st.Unmarshal(b)
-	if err != nil {
-		err = fmt.Errorf("error in unmarshaling SPNEGO token: %v", err)
-		spnegoNegotiateKRB5MechType(spnego, w, "%s - SPNEGO %v", r.RemoteAddr, err)
-		return nil, err
-	}
-	return &st, nil
-}
-
-func getSessionCredentials(spnego *SPNEGO, r *http.Request) (credentials.Credentials, error) {
-	var creds credentials.Credentials
-	// Check if there is a session manager and if there is an already established session for this client
-	if sm := spnego.serviceSettings.SessionManager(); sm != nil {
-		cb, err := sm.Get(r, sessionCredentials)
-		if err != nil || cb == nil || len(cb) < 1 {
-			return creds, fmt.Errorf("%s - SPNEGO error getting session and credentials for request: %v", r.RemoteAddr, err)
-		}
-		err = creds.Unmarshal(cb)
-		if err != nil {
-			return creds, fmt.Errorf("%s - SPNEGO credentials malformed in session: %v", r.RemoteAddr, err)
-		}
-		return creds, nil
-	}
-	return creds, errors.New("no session manager configured")
-}
-
-func newSession(spnego *SPNEGO, r *http.Request, w http.ResponseWriter, id *credentials.Credentials) error {
-	if sm := spnego.serviceSettings.SessionManager(); sm != nil {
-		// create new session
-		idb, err := id.Marshal()
-		if err != nil {
-			spnegoInternalServerError(spnego, w, "SPNEGO could not marshal credentials to add to the session: %v", err)
-			return err
-		}
-		err = sm.New(w, r, sessionCredentials, idb)
-		if err != nil {
-			spnegoInternalServerError(spnego, w, "SPNEGO could not create new session: %v", err)
-			return err
-		}
-		spnego.Log("%s %s@%s - SPNEGO new session (%s) created", r.RemoteAddr, id.UserName(), id.Domain(), id.SessionID())
-	}
-	return nil
-}
-
-// Log and respond to client for error conditions
-
 func spnegoNegotiateKRB5MechType(s *SPNEGO, w http.ResponseWriter, format string, v ...interface{}) {
 	s.Log(format, v...)
 	w.Header().Set(HTTPHeaderAuthResponse, spnegoNegTokenRespIncompleteKRB5)
@@ -351,8 +291,3 @@ func spnegoResponseAcceptCompleted(s *SPNEGO, w http.ResponseWriter, format stri
 	s.Log(format, v...)
 	w.Header().Set(HTTPHeaderAuthResponse, spnegoNegTokenRespKRBAcceptCompleted)
 }
-
-func spnegoInternalServerError(s *SPNEGO, w http.ResponseWriter, format string, v ...interface{}) {
-	s.Log(format, v...)
-	http.Error(w, "Internal Server Error", http.StatusInternalServerError)
-}
diff --git a/spnego/krb5Token.go b/spnego/krb5Token.go
index 29eab7d..73bd64d 100644
--- a/spnego/krb5Token.go
+++ b/spnego/krb5Token.go
@@ -70,8 +70,8 @@ func (m *KRB5Token) Unmarshal(b []byte) error {
 	if err != nil {
 		return fmt.Errorf("error unmarshalling KRB5Token OID: %v", err)
 	}
-	if !oid.Equal(gssapi.OIDKRB5.OID()) {
-		return fmt.Errorf("error unmarshalling KRB5Token, OID is %s not %s", oid.String(), gssapi.OIDKRB5.OID().String())
+	if !oid.Equal(gssapi.OID(gssapi.OIDKRB5)) {
+		return fmt.Errorf("error unmarshalling KRB5Token, OID is %s not %s", oid.String(), gssapi.OID(gssapi.OIDKRB5).String())
 	}
 	m.OID = oid
 	if len(r) < 2 {
@@ -108,7 +108,7 @@ func (m *KRB5Token) Unmarshal(b []byte) error {
 func (m *KRB5Token) Verify() (bool, gssapi.Status) {
 	switch hex.EncodeToString(m.tokID) {
 	case TOK_ID_KRB_AP_REQ:
-		ok, creds, err := service.VerifyAPREQ(&m.APReq, m.settings)
+		ok, creds, err := service.VerifyAPREQ(m.APReq, m.settings)
 		if err != nil {
 			return false, gssapi.Status{Code: gssapi.StatusDefectiveToken, Message: err.Error()}
 		}
@@ -116,7 +116,8 @@ func (m *KRB5Token) Verify() (bool, gssapi.Status) {
 			return false, gssapi.Status{Code: gssapi.StatusDefectiveCredential, Message: "KRB5_AP_REQ token not valid"}
 		}
 		m.context = context.Background()
-		m.context = context.WithValue(m.context, ctxCredentials, creds)
+		m.context = context.WithValue(m.context, CTXKeyCredentials, creds)
+		m.context = context.WithValue(m.context, CTXKeyAuthenticated, ok)
 		return true, gssapi.Status{Code: gssapi.StatusComplete}
 	case TOK_ID_KRB_AP_REP:
 		// Client side
@@ -164,7 +165,7 @@ func (m *KRB5Token) Context() context.Context {
 func NewKRB5TokenAPREQ(cl *client.Client, tkt messages.Ticket, sessionKey types.EncryptionKey, GSSAPIFlags []int, APOptions []int) (KRB5Token, error) {
 	// TODO consider providing the SPN rather than the specific tkt and key and get these from the krb client.
 	var m KRB5Token
-	m.OID = gssapi.OIDKRB5.OID()
+	m.OID = gssapi.OID(gssapi.OIDKRB5)
 	tb, _ := hex.DecodeString(TOK_ID_KRB_AP_REQ)
 	m.tokID = tb
 
diff --git a/spnego/negotiationToken.go b/spnego/negotiationToken.go
index fa1f3ee..34d305f 100644
--- a/spnego/negotiationToken.go
+++ b/spnego/negotiationToken.go
@@ -142,7 +142,7 @@ func (n *NegTokenInit) Verify() (bool, gssapi.Status) {
 	// Check if supported mechanisms are in the MechTypeList
 	var mtSupported bool
 	for _, m := range n.MechTypes {
-		if m.Equal(gssapi.OIDKRB5.OID()) || m.Equal(gssapi.OIDMSLegacyKRB5.OID()) {
+		if m.Equal(gssapi.OID(gssapi.OIDKRB5)) || m.Equal(gssapi.OID(gssapi.OIDMSLegacyKRB5)) {
 			if n.mechToken == nil && n.MechTokenBytes == nil {
 				return false, gssapi.Status{Code: gssapi.StatusContinueNeeded}
 			}
@@ -229,7 +229,7 @@ func (n *NegTokenResp) Unmarshal(b []byte) error {
 
 // Verify a Resp/Targ negotiation token
 func (n *NegTokenResp) Verify() (bool, gssapi.Status) {
-	if n.SupportedMech.Equal(gssapi.OIDKRB5.OID()) || n.SupportedMech.Equal(gssapi.OIDMSLegacyKRB5.OID()) {
+	if n.SupportedMech.Equal(gssapi.OID(gssapi.OIDKRB5)) || n.SupportedMech.Equal(gssapi.OID(gssapi.OIDMSLegacyKRB5)) {
 		if n.mechToken == nil && n.ResponseToken == nil {
 			return false, gssapi.Status{Code: gssapi.StatusContinueNeeded}
 		}
@@ -328,7 +328,7 @@ func NewNegTokenInitKRB5(cl *client.Client, tkt messages.Ticket, sessionKey type
 		return NegTokenInit{}, fmt.Errorf("error marshalling KRB5 token; %v", err)
 	}
 	return NegTokenInit{
-		MechTypes:      []asn1.ObjectIdentifier{gssapi.OIDKRB5.OID()},
+		MechTypes:      []asn1.ObjectIdentifier{gssapi.OID(gssapi.OIDKRB5)},
 		MechTokenBytes: mtb,
 	}, nil
 }
diff --git a/spnego/spnego.go b/spnego/spnego.go
index fa221c1..b368d64 100644
--- a/spnego/spnego.go
+++ b/spnego/spnego.go
@@ -39,7 +39,7 @@ func SPNEGOService(kt *keytab.Keytab, options ...func(*service.Settings)) *SPNEG
 
 // OID returns the GSS-API assigned OID for SPNEGO.
 func (s *SPNEGO) OID() asn1.ObjectIdentifier {
-	return gssapi.OIDSPNEGO.OID()
+	return gssapi.OID(gssapi.OIDSPNEGO)
 }
 
 // AcquireCred is the GSS-API method to acquire a client credential via Kerberos for SPNEGO.
@@ -80,7 +80,7 @@ func (s *SPNEGO) AcceptSecContext(ct gssapi.ContextToken) (bool, context.Context
 	if t.Resp {
 		oid = t.NegTokenResp.SupportedMech
 	}
-	if !(oid.Equal(gssapi.OIDKRB5.OID()) || oid.Equal(gssapi.OIDMSLegacyKRB5.OID())) {
+	if !(oid.Equal(gssapi.OID(gssapi.OIDKRB5)) || oid.Equal(gssapi.OID(gssapi.OIDMSLegacyKRB5))) {
 		return false, ctx, gssapi.Status{Code: gssapi.StatusDefectiveToken, Message: "SPNEGO OID of MechToken is not of type KRB5"}
 	}
 	// Flags in the NegInit must be used 	t.NegTokenInit.ReqFlags
@@ -110,7 +110,7 @@ type SPNEGOToken struct {
 func (s *SPNEGOToken) Marshal() ([]byte, error) {
 	var b []byte
 	if s.Init {
-		hb, _ := asn1.Marshal(gssapi.OIDSPNEGO.OID())
+		hb, _ := asn1.Marshal(gssapi.OID(gssapi.OIDSPNEGO))
 		tb, err := s.NegTokenInit.Marshal()
 		if err != nil {
 			return b, fmt.Errorf("could not marshal NegTokenInit: %v", err)
@@ -144,7 +144,7 @@ func (s *SPNEGOToken) Unmarshal(b []byte) error {
 			return fmt.Errorf("not a valid SPNEGO token: %v", err)
 		}
 		// Check the OID is the SPNEGO OID value
-		SPNEGOOID := gssapi.OIDSPNEGO.OID()
+		SPNEGOOID := gssapi.OID(gssapi.OIDSPNEGO)
 		if !oid.Equal(SPNEGOOID) {
 			return fmt.Errorf("OID %s does not match SPNEGO OID %s", oid.String(), SPNEGOOID.String())
 		}


Test patch:
diff --git a/client/client_ad_integration_test.go b/client/client_ad_integration_test.go
index f6da1fa..f573a4c 100644
--- a/client/client_ad_integration_test.go
+++ b/client/client_ad_integration_test.go
@@ -23,9 +23,9 @@ func TestClient_SuccessfulLogin_AD(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	c.Realms[0].KDC = []string{testdata.TEST_KDC_AD}
-	cl := NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+	cl := NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 
 	err := cl.Login()
 	if err != nil {
@@ -39,9 +39,9 @@ func TestClient_GetServiceTicket_AD(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	c.Realms[0].KDC = []string{testdata.TEST_KDC_AD}
-	cl := NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+	cl := NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 
 	err := cl.Login()
 	if err != nil {
@@ -80,10 +80,10 @@ func TestClient_SuccessfulLogin_AD_TRUST_USER_DOMAIN(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_USERKRB5_AD_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	c.Realms[0].KDC = []string{testdata.TEST_KDC_AD_TRUST_USER_DOMAIN}
 	c.LibDefaults.DefaultRealm = "USER.GOKRB5"
-	cl := NewWithKeytab("testuser1", "USER.GOKRB5", kt, c, DisablePAFXFAST(true))
+	cl := NewClientWithKeytab("testuser1", "USER.GOKRB5", kt, c, DisablePAFXFAST(true))
 
 	err := cl.Login()
 	if err != nil {
@@ -97,7 +97,7 @@ func TestClient_GetServiceTicket_AD_TRUST_USER_DOMAIN(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_USERKRB5_AD_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	c.Realms[0].KDC = []string{testdata.TEST_KDC_AD_TRUST_USER_DOMAIN}
 	c.LibDefaults.DefaultRealm = "USER.GOKRB5"
 	c.LibDefaults.Canonicalize = true
@@ -105,7 +105,7 @@ func TestClient_GetServiceTicket_AD_TRUST_USER_DOMAIN(t *testing.T) {
 	c.LibDefaults.DefaultTktEnctypeIDs = []int32{etypeID.ETypesByName["rc4-hmac"]}
 	c.LibDefaults.DefaultTGSEnctypes = []string{"rc4-hmac"}
 	c.LibDefaults.DefaultTGSEnctypeIDs = []int32{etypeID.ETypesByName["rc4-hmac"]}
-	cl := NewWithKeytab("testuser1", "USER.GOKRB5", kt, c, DisablePAFXFAST(true))
+	cl := NewClientWithKeytab("testuser1", "USER.GOKRB5", kt, c, DisablePAFXFAST(true))
 
 	err := cl.Login()
 
@@ -146,7 +146,7 @@ func TestClient_GetServiceTicket_AD_USER_DOMAIN(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_USERKRB5_AD_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	c.Realms[0].KDC = []string{testdata.TEST_KDC_AD_TRUST_USER_DOMAIN}
 	c.LibDefaults.DefaultRealm = "USER.GOKRB5"
 	c.LibDefaults.Canonicalize = true
@@ -154,7 +154,7 @@ func TestClient_GetServiceTicket_AD_USER_DOMAIN(t *testing.T) {
 	c.LibDefaults.DefaultTktEnctypeIDs = []int32{etypeID.ETypesByName["rc4-hmac"]}
 	c.LibDefaults.DefaultTGSEnctypes = []string{"rc4-hmac"}
 	c.LibDefaults.DefaultTGSEnctypeIDs = []int32{etypeID.ETypesByName["rc4-hmac"]}
-	cl := NewWithKeytab("testuser1", "USER.GOKRB5", kt, c, DisablePAFXFAST(true))
+	cl := NewClientWithKeytab("testuser1", "USER.GOKRB5", kt, c, DisablePAFXFAST(true))
 
 	err := cl.Login()
 
diff --git a/client/client_dns_test.go b/client/client_dns_test.go
index 11e21da..1d1a68f 100644
--- a/client/client_dns_test.go
+++ b/client/client_dns_test.go
@@ -16,7 +16,7 @@ func TestClient_Login_DNSKDCs(t *testing.T) {
 	//if ns == "" {
 	//	os.Setenv("DNSUTILS_OVERRIDE_NS", testdata.TEST_NS)
 	//}
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	// Set to lookup KDCs in DNS
 	c.LibDefaults.DNSLookupKDC = true
 	//Blank out the KDCs to ensure they are not being used
@@ -25,7 +25,7 @@ func TestClient_Login_DNSKDCs(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	cl := NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+	cl := NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 
 	err := cl.Login()
 	if err != nil {
diff --git a/client/client_integration_test.go b/client/client_integration_test.go
index 9aba6bc..1ee3a87 100644
--- a/client/client_integration_test.go
+++ b/client/client_integration_test.go
@@ -37,7 +37,7 @@ func TestClient_SuccessfulLogin_Keytab(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	var tests = []string{
 		testdata.TEST_KDC,
 		testdata.TEST_KDC_OLD,
@@ -45,7 +45,7 @@ func TestClient_SuccessfulLogin_Keytab(t *testing.T) {
 	}
 	for _, tst := range tests {
 		c.Realms[0].KDC = []string{addr + ":" + tst}
-		cl := client.NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+		cl := client.NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 
 		err := cl.Login()
 		if err != nil {
@@ -61,7 +61,7 @@ func TestClient_SuccessfulLogin_Password(t *testing.T) {
 	if addr == "" {
 		addr = testdata.TEST_KDC_ADDR
 	}
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	var tests = []string{
 		testdata.TEST_KDC,
 		testdata.TEST_KDC_OLD,
@@ -69,7 +69,7 @@ func TestClient_SuccessfulLogin_Password(t *testing.T) {
 	}
 	for _, tst := range tests {
 		c.Realms[0].KDC = []string{addr + ":" + tst}
-		cl := client.NewWithPassword("testuser1", "TEST.GOKRB5", "passwordvalue", c)
+		cl := client.NewClientWithPassword("testuser1", "TEST.GOKRB5", "passwordvalue", c)
 
 		err := cl.Login()
 		if err != nil {
@@ -84,14 +84,14 @@ func TestClient_SuccessfulLogin_TCPOnly(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
 		addr = testdata.TEST_KDC_ADDR
 	}
 	c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
 	c.LibDefaults.UDPPreferenceLimit = 1
-	cl := client.NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+	cl := client.NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 
 	err := cl.Login()
 	if err != nil {
@@ -105,7 +105,7 @@ func TestClient_ASExchange_TGSExchange_EncTypes_Keytab(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
 		addr = testdata.TEST_KDC_ADDR
@@ -124,7 +124,7 @@ func TestClient_ASExchange_TGSExchange_EncTypes_Keytab(t *testing.T) {
 		c.LibDefaults.DefaultTktEnctypeIDs = []int32{etypeID.ETypesByName[tst]}
 		c.LibDefaults.DefaultTGSEnctypes = []string{tst}
 		c.LibDefaults.DefaultTGSEnctypeIDs = []int32{etypeID.ETypesByName[tst]}
-		cl := client.NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+		cl := client.NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 
 		err := cl.Login()
 		if err != nil {
@@ -142,7 +142,7 @@ func TestClient_ASExchange_TGSExchange_EncTypes_Keytab(t *testing.T) {
 func TestClient_ASExchange_TGSExchange_EncTypes_Password(t *testing.T) {
 	test.Integration(t)
 
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
 		addr = testdata.TEST_KDC_ADDR
@@ -161,7 +161,7 @@ func TestClient_ASExchange_TGSExchange_EncTypes_Password(t *testing.T) {
 		c.LibDefaults.DefaultTktEnctypeIDs = []int32{etypeID.ETypesByName[tst]}
 		c.LibDefaults.DefaultTGSEnctypes = []string{tst}
 		c.LibDefaults.DefaultTGSEnctypeIDs = []int32{etypeID.ETypesByName[tst]}
-		cl := client.NewWithPassword("testuser1", "TEST.GOKRB5", "passwordvalue", c)
+		cl := client.NewClientWithPassword("testuser1", "TEST.GOKRB5", "passwordvalue", c)
 
 		err := cl.Login()
 		if err != nil {
@@ -182,13 +182,13 @@ func TestClient_FailedLogin(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_WRONGPASSWD)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
 		addr = testdata.TEST_KDC_ADDR
 	}
 	c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
-	cl := client.NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+	cl := client.NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 
 	err := cl.Login()
 	if err == nil {
@@ -202,13 +202,13 @@ func TestClient_SuccessfulLogin_UserRequiringPreAuth(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER2_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
 		addr = testdata.TEST_KDC_ADDR
 	}
 	c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
-	cl := client.NewWithKeytab("testuser2", "TEST.GOKRB5", kt, c)
+	cl := client.NewClientWithKeytab("testuser2", "TEST.GOKRB5", kt, c)
 
 	err := cl.Login()
 	if err != nil {
@@ -222,14 +222,14 @@ func TestClient_SuccessfulLogin_UserRequiringPreAuth_TCPOnly(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER2_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
 		addr = testdata.TEST_KDC_ADDR
 	}
 	c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
 	c.LibDefaults.UDPPreferenceLimit = 1
-	cl := client.NewWithKeytab("testuser2", "TEST.GOKRB5", kt, c)
+	cl := client.NewClientWithKeytab("testuser2", "TEST.GOKRB5", kt, c)
 
 	err := cl.Login()
 	if err != nil {
@@ -243,9 +243,9 @@ func TestClient_NetworkTimeout(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	c.Realms[0].KDC = []string{testdata.TEST_KDC_BADADDR + ":88"}
-	cl := client.NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+	cl := client.NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 
 	err := cl.Login()
 	if err == nil {
@@ -259,13 +259,13 @@ func TestClient_GetServiceTicket(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
 		addr = testdata.TEST_KDC_ADDR
 	}
 	c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
-	cl := client.NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+	cl := client.NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 
 	err := cl.Login()
 	if err != nil {
@@ -294,13 +294,13 @@ func TestClient_GetServiceTicket_InvalidSPN(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
 		addr = testdata.TEST_KDC_ADDR
 	}
 	c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
-	cl := client.NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+	cl := client.NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 
 	err := cl.Login()
 	if err != nil {
@@ -318,13 +318,13 @@ func TestClient_GetServiceTicket_OlderKDC(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
 		addr = testdata.TEST_KDC_ADDR
 	}
 	c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC_OLD}
-	cl := client.NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+	cl := client.NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 
 	err := cl.Login()
 	if err != nil {
@@ -345,13 +345,13 @@ func TestMultiThreadedClientUse(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
 		addr = testdata.TEST_KDC_ADDR
 	}
 	c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
-	cl := client.NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+	cl := client.NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 
 	var wg sync.WaitGroup
 	wg.Add(5)
@@ -407,7 +407,7 @@ func spnegoGet(cl *client.Client) error {
 	return nil
 }
 
-func TestNewFromCCache(t *testing.T) {
+func TestNewClientFromCCache(t *testing.T) {
 	test.Integration(t)
 
 	b, err := hex.DecodeString(testdata.CCACHE_TEST)
@@ -419,13 +419,13 @@ func TestNewFromCCache(t *testing.T) {
 	if err != nil {
 		t.Fatal("error getting test CCache")
 	}
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
 		addr = testdata.TEST_KDC_ADDR
 	}
 	c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
-	cl, err := client.NewFromCCache(cc, c)
+	cl, err := client.NewClientFromCCache(cc, c)
 	if err != nil {
 		t.Fatalf("error creating client from CCache: %v", err)
 	}
@@ -442,7 +442,7 @@ func TestClient_GetServiceTicket_Trusted_Resource_Domain(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
@@ -458,7 +458,7 @@ func TestClient_GetServiceTicket_Trusted_Resource_Domain(t *testing.T) {
 	}
 
 	c.LibDefaults.DefaultRealm = "TEST.GOKRB5"
-	cl := client.NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+	cl := client.NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 	c.LibDefaults.DefaultTktEnctypes = []string{"aes256-cts-hmac-sha1-96"}
 	c.LibDefaults.DefaultTktEnctypeIDs = []int32{etypeID.ETypesByName["aes256-cts-hmac-sha1-96"]}
 	c.LibDefaults.DefaultTGSEnctypes = []string{"aes256-cts-hmac-sha1-96"}
@@ -559,13 +559,13 @@ func TestGetServiceTicketFromCCacheTGT(t *testing.T) {
 	if err != nil {
 		t.Errorf("error loading CCache: %v", err)
 	}
-	cfg, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	cfg, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
 		addr = testdata.TEST_KDC_ADDR
 	}
 	cfg.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
-	cl, err := client.NewFromCCache(c, cfg)
+	cl, err := client.NewClientFromCCache(c, cfg)
 	if err != nil {
 		t.Fatalf("error generating client from ccache: %v", err)
 	}
@@ -616,8 +616,8 @@ func TestGetServiceTicketFromCCacheWithoutKDC(t *testing.T) {
 	if err != nil {
 		t.Errorf("error loading CCache: %v", err)
 	}
-	cfg, _ := config.NewFromString("...")
-	cl, err := client.NewFromCCache(c, cfg)
+	cfg, _ := config.NewConfigFromString("...")
+	cl, err := client.NewClientFromCCache(c, cfg)
 	if err != nil {
 		t.Fatalf("error generating client from ccache: %v", err)
 	}
@@ -643,14 +643,14 @@ func TestClient_ChangePasswd(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
 		addr = testdata.TEST_KDC_ADDR
 	}
 	c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
 	c.Realms[0].KPasswdServer = []string{addr + ":464"}
-	cl := client.NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+	cl := client.NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 
 	ok, err := cl.ChangePasswd("newpassword")
 	if err != nil {
@@ -658,14 +658,14 @@ func TestClient_ChangePasswd(t *testing.T) {
 	}
 	assert.True(t, ok, "password was not changed")
 
-	cl = client.NewWithPassword("testuser1", "TEST.GOKRB5", "newpassword", c)
+	cl = client.NewClientWithPassword("testuser1", "TEST.GOKRB5", "newpassword", c)
 	ok, err = cl.ChangePasswd(testdata.TESTUSER1_PASSWORD)
 	if err != nil {
 		t.Fatalf("error changing password: %v", err)
 	}
 	assert.True(t, ok, "password was not changed back")
 
-	cl = client.NewWithPassword("testuser1", "TEST.GOKRB5", testdata.TESTUSER1_PASSWORD, c)
+	cl = client.NewClientWithPassword("testuser1", "TEST.GOKRB5", testdata.TESTUSER1_PASSWORD, c)
 	err = cl.Login()
 	if err != nil {
 		t.Fatalf("Could not log back in after reverting password: %v", err)
@@ -682,9 +682,9 @@ func TestClient_Destroy(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC_SHORTTICKETS}
-	cl := client.NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+	cl := client.NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 
 	err := cl.Login()
 	if err != nil {
diff --git a/client/client_test.go b/client/client_test.go
index ed0eb2d..4ae4ed0 100644
--- a/client/client_test.go
+++ b/client/client_test.go
@@ -10,7 +10,7 @@ import (
 func TestAssumePreauthentication(t *testing.T) {
 	t.Parallel()
 
-	cl := NewWithKeytab("username", "REALM", &keytab.Keytab{}, &config.Config{}, AssumePreAuthentication(true))
+	cl := NewClientWithKeytab("username", "REALM", &keytab.Keytab{}, &config.Config{}, AssumePreAuthentication(true))
 	if !cl.settings.assumePreAuthentication {
 		t.Fatal("assumePreAuthentication should be true")
 	}
diff --git a/client/session_test.go b/client/session_test.go
index 8addd11..be1bd07 100644
--- a/client/session_test.go
+++ b/client/session_test.go
@@ -24,13 +24,13 @@ func TestMultiThreadedClientSession(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
 		addr = testdata.TEST_KDC_ADDR
 	}
 	c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
-	cl := NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+	cl := NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 	err := cl.Login()
 	if err != nil {
 		t.Fatalf("failed to log in: %v", err)
@@ -78,10 +78,10 @@ func TestClient_AutoRenew_Goroutine(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER2_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC_SHORTTICKETS}
 	c.LibDefaults.PreferredPreauthTypes = []int{int(etypeID.DES3_CBC_SHA1_KD)} // a preauth etype the KDC does not support. Test this does not cause renewal to fail.
-	cl := NewWithKeytab("testuser2", "TEST.GOKRB5", kt, c)
+	cl := NewClientWithKeytab("testuser2", "TEST.GOKRB5", kt, c)
 
 	err := cl.Login()
 	if err != nil {
diff --git a/config/hosts_test.go b/config/hosts_test.go
index 92d3bae..3e8c728 100644
--- a/config/hosts_test.go
+++ b/config/hosts_test.go
@@ -23,7 +23,7 @@ func TestConfig_GetKDCsUsesConfiguredKDC(t *testing.T) {
  }
 `
 
-	c, err := NewFromString(krb5ConfWithKDCAndDNSLookupKDC)
+	c, err := NewConfigFromString(krb5ConfWithKDCAndDNSLookupKDC)
 	if err != nil {
 		t.Fatalf("Error loading config: %v", err)
 	}
@@ -43,7 +43,7 @@ func TestConfig_GetKDCsUsesConfiguredKDC(t *testing.T) {
 func TestResolveKDC(t *testing.T) {
 	test.Privileged(t)
 
-	c, err := NewFromString(testdata.TEST_KRB5CONF)
+	c, err := NewConfigFromString(testdata.TEST_KRB5CONF)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/config/krb5conf_test.go b/config/krb5conf_test.go
index e38ef0b..eca779a 100644
--- a/config/krb5conf_test.go
+++ b/config/krb5conf_test.go
@@ -381,7 +381,7 @@ func TestLoadWithV4Lines(t *testing.T) {
 
 func TestLoad2(t *testing.T) {
 	t.Parallel()
-	c, err := NewFromString(krb5Conf2)
+	c, err := NewConfigFromString(krb5Conf2)
 	if err != nil {
 		t.Fatalf("Error loading config: %v", err)
 	}
@@ -411,7 +411,7 @@ func TestLoad2(t *testing.T) {
 
 func TestLoadNoBlankLines(t *testing.T) {
 	t.Parallel()
-	c, err := NewFromString(krb5ConfNoBlankLines)
+	c, err := NewConfigFromString(krb5ConfNoBlankLines)
 	if err != nil {
 		t.Fatalf("Error loading config: %v", err)
 	}
@@ -504,7 +504,7 @@ func TestParseDuration(t *testing.T) {
 
 func TestResolveRealm(t *testing.T) {
 	t.Parallel()
-	c, err := NewFromString(krb5Conf)
+	c, err := NewConfigFromString(krb5Conf)
 	if err != nil {
 		t.Fatalf("Error loading config: %v", err)
 	}
diff --git a/credentials/credentials_test.go b/credentials/credentials_test.go
index 7ce4f7c..c774c27 100644
--- a/credentials/credentials_test.go
+++ b/credentials/credentials_test.go
@@ -1,10 +1,9 @@
 package credentials
 
 import (
-	"testing"
-
 	"github.com/stretchr/testify/assert"
-	"gopkg.in/jcmturner/goidentity.v5"
+	goidentity "gopkg.in/jcmturner/goidentity.v3"
+	"testing"
 )
 
 func TestImplementsInterface(t *testing.T) {
@@ -13,16 +12,3 @@ func TestImplementsInterface(t *testing.T) {
 	i := new(goidentity.Identity)
 	assert.Implements(t, i, u, "Credentials type does not implement the Identity interface")
 }
-
-func TestCredentials_Marshal(t *testing.T) {
-	var cred Credentials
-	b, err := cred.Marshal()
-	if err != nil {
-		t.Fatalf("could not marshal credetials: %v", err)
-	}
-	var credum Credentials
-	err = credum.Unmarshal(b)
-	if err != nil {
-		t.Fatalf("could not unmarshal credetials: %v", err)
-	}
-}
diff --git a/gssapi/gssapi_test.go b/gssapi/gssapi_test.go
index 3c3f016..425430d 100644
--- a/gssapi/gssapi_test.go
+++ b/gssapi/gssapi_test.go
@@ -15,11 +15,10 @@ func TestOID(t *testing.T) {
 		{OIDMSLegacyKRB5, []int{1, 2, 840, 48018, 1, 2, 2}},
 		{OIDKRB5, []int{1, 2, 840, 113554, 1, 2, 2}},
 		{OIDSPNEGO, []int{1, 3, 6, 1, 5, 5, 2}},
-		{OIDGSSIAKerb, []int{1, 3, 6, 1, 5, 2, 5}},
 	}
 
 	for _, tst := range tests {
 		oid := asn1.ObjectIdentifier(tst.oid)
-		assert.True(t, oid.Equal(OIDName(tst.name).OID()), "OID value not as expected for %s", tst.name)
+		assert.True(t, oid.Equal(OID(tst.name)), "OID value not as expected for %s", tst.name)
 	}
 }
diff --git a/pac/pac_type_test.go b/pac/pac_type_test.go
index b6b64a6..9fb0dde 100644
--- a/pac/pac_type_test.go
+++ b/pac/pac_type_test.go
@@ -29,7 +29,7 @@ func TestPACTypeVerify(t *testing.T) {
 	kt := keytab.New()
 	kt.Unmarshal(b)
 	pn, _ := types.ParseSPNString("sysHTTP")
-	key, _, err := kt.GetEncryptionKey(pn, "TEST.GOKRB5", 2, 18)
+	key, err := kt.GetEncryptionKey(pn, "TEST.GOKRB5", 2, 18)
 	if err != nil {
 		t.Fatalf("Error getting key: %v", err)
 	}
diff --git a/service/APExchange_test.go b/service/APExchange_test.go
index 37175f7..d4d3302 100644
--- a/service/APExchange_test.go
+++ b/service/APExchange_test.go
@@ -54,7 +54,7 @@ func TestVerifyAPREQ(t *testing.T) {
 
 	h, _ := types.GetHostAddress("127.0.0.1:1234")
 	s := NewSettings(kt, ClientAddress(h))
-	ok, _, err := VerifyAPREQ(&APReq, s)
+	ok, _, err := VerifyAPREQ(APReq, s)
 	if !ok || err != nil {
 		t.Fatalf("Validation of AP_REQ failed when it should not have: %v", err)
 	}
@@ -100,7 +100,7 @@ func TestVerifyAPREQ_KRB_AP_ERR_BADMATCH(t *testing.T) {
 	}
 	h, _ := types.GetHostAddress("127.0.0.1:1234")
 	s := NewSettings(kt, ClientAddress(h))
-	ok, _, err := VerifyAPREQ(&APReq, s)
+	ok, _, err := VerifyAPREQ(APReq, s)
 	if ok || err == nil {
 		t.Fatal("Validation of AP_REQ passed when it should not have")
 	}
@@ -149,7 +149,7 @@ func TestVerifyAPREQ_LargeClockSkew(t *testing.T) {
 
 	h, _ := types.GetHostAddress("127.0.0.1:1234")
 	s := NewSettings(kt, ClientAddress(h))
-	ok, _, err := VerifyAPREQ(&APReq, s)
+	ok, _, err := VerifyAPREQ(APReq, s)
 	if ok || err == nil {
 		t.Fatal("Validation of AP_REQ passed when it should not have")
 	}
@@ -196,12 +196,12 @@ func TestVerifyAPREQ_Replay(t *testing.T) {
 
 	h, _ := types.GetHostAddress("127.0.0.1:1234")
 	s := NewSettings(kt, ClientAddress(h))
-	ok, _, err := VerifyAPREQ(&APReq, s)
+	ok, _, err := VerifyAPREQ(APReq, s)
 	if !ok || err != nil {
 		t.Fatalf("Validation of AP_REQ failed when it should not have: %v", err)
 	}
 	// Replay
-	ok, _, err = VerifyAPREQ(&APReq, s)
+	ok, _, err = VerifyAPREQ(APReq, s)
 	if ok || err == nil {
 		t.Fatal("Validation of AP_REQ passed when it should not have")
 	}
@@ -246,7 +246,7 @@ func TestVerifyAPREQ_FutureTicket(t *testing.T) {
 
 	h, _ := types.GetHostAddress("127.0.0.1:1234")
 	s := NewSettings(kt, ClientAddress(h))
-	ok, _, err := VerifyAPREQ(&APReq, s)
+	ok, _, err := VerifyAPREQ(APReq, s)
 	if ok || err == nil {
 		t.Fatal("Validation of AP_REQ passed when it should not have")
 	}
@@ -295,7 +295,7 @@ func TestVerifyAPREQ_InvalidTicket(t *testing.T) {
 
 	h, _ := types.GetHostAddress("127.0.0.1:1234")
 	s := NewSettings(kt, ClientAddress(h))
-	ok, _, err := VerifyAPREQ(&APReq, s)
+	ok, _, err := VerifyAPREQ(APReq, s)
 	if ok || err == nil {
 		t.Fatal("Validation of AP_REQ passed when it should not have")
 	}
@@ -343,7 +343,7 @@ func TestVerifyAPREQ_ExpiredTicket(t *testing.T) {
 
 	h, _ := types.GetHostAddress("127.0.0.1:1234")
 	s := NewSettings(kt, ClientAddress(h))
-	ok, _, err := VerifyAPREQ(&APReq, s)
+	ok, _, err := VerifyAPREQ(APReq, s)
 	if ok || err == nil {
 		t.Fatal("Validation of AP_REQ passed when it should not have")
 	}
@@ -368,7 +368,7 @@ func getClient() *client.Client {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
-	cl := client.NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
+	cl := client.NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 	return cl
 }
diff --git a/service/authenticator_test.go b/service/authenticator_test.go
index 5ac3781..742e2c0 100644
--- a/service/authenticator_test.go
+++ b/service/authenticator_test.go
@@ -4,7 +4,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
-	"gopkg.in/jcmturner/goidentity.v5"
+	"gopkg.in/jcmturner/goidentity.v3"
 )
 
 func TestImplementsInterface(t *testing.T) {
diff --git a/spnego/http_test.go b/spnego/http_test.go
index 5bc6bab..b9c8175 100644
--- a/spnego/http_test.go
+++ b/spnego/http_test.go
@@ -4,22 +4,19 @@ import (
 	"bytes"
 	"crypto/rand"
 	"encoding/hex"
-	"errors"
 	"fmt"
 	"io"
 	"io/ioutil"
 	"log"
 	"mime/multipart"
 	"net/http"
-	"net/http/cookiejar"
 	"net/http/httptest"
 	"os"
 	"sync"
 	"testing"
 
-	"github.com/gorilla/sessions"
 	"github.com/stretchr/testify/assert"
-	"gopkg.in/jcmturner/goidentity.v5"
+	"gopkg.in/jcmturner/goidentity.v3"
 	"gopkg.in/jcmturner/gokrb5.v7/client"
 	"gopkg.in/jcmturner/gokrb5.v7/config"
 	"gopkg.in/jcmturner/gokrb5.v7/keytab"
@@ -33,14 +30,14 @@ func TestClient_SetSPNEGOHeader(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
 		addr = testdata.TEST_KDC_ADDR
 	}
 	c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
 	l := log.New(os.Stderr, "SPNEGO Client:", log.LstdFlags)
-	cl := client.NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c, client.Logger(l))
+	cl := client.NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c, client.Logger(l))
 
 	err := cl.Login()
 	if err != nil {
@@ -82,14 +79,14 @@ func TestSPNEGOHTTPClient(t *testing.T) {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
 		addr = testdata.TEST_KDC_ADDR
 	}
 	c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
 	l := log.New(os.Stderr, "SPNEGO Client:", log.LstdFlags)
-	cl := client.NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c, client.Logger(l))
+	cl := client.NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c, client.Logger(l))
 
 	err := cl.Login()
 	if err != nil {
@@ -158,7 +155,7 @@ func TestService_SPNEGOKRB_ValidUser(t *testing.T) {
 func TestService_SPNEGOKRB_Replay(t *testing.T) {
 	test.Integration(t)
 
-	s := httpServerWithoutSessionManager()
+	s := httpServer()
 	defer s.Close()
 	r1, _ := http.NewRequest("GET", s.URL, nil)
 
@@ -215,7 +212,7 @@ func TestService_SPNEGOKRB_Replay(t *testing.T) {
 func TestService_SPNEGOKRB_ReplayCache_Concurrency(t *testing.T) {
 	test.Integration(t)
 
-	s := httpServerWithoutSessionManager()
+	s := httpServer()
 	defer s.Close()
 	r1, _ := http.NewRequest("GET", s.URL, nil)
 
@@ -224,7 +221,6 @@ func TestService_SPNEGOKRB_ReplayCache_Concurrency(t *testing.T) {
 	if err != nil {
 		t.Fatalf("error setting client's SPNEGO header: %v", err)
 	}
-	r1h := r1.Header.Get(HTTPHeaderAuthRequest)
 
 	r2, _ := http.NewRequest("GET", s.URL, nil)
 
@@ -232,7 +228,6 @@ func TestService_SPNEGOKRB_ReplayCache_Concurrency(t *testing.T) {
 	if err != nil {
 		t.Fatalf("error setting client's SPNEGO header: %v", err)
 	}
-	r2h := r2.Header.Get(HTTPHeaderAuthRequest)
 
 	// Concurrent 1st requests should be OK
 	var wg sync.WaitGroup
@@ -246,12 +241,8 @@ func TestService_SPNEGOKRB_ReplayCache_Concurrency(t *testing.T) {
 	noReq := 10
 	wg2.Add(noReq * 2)
 	for i := 0; i < noReq; i++ {
-		rr1, _ := http.NewRequest("GET", s.URL, nil)
-		rr1.Header.Set(HTTPHeaderAuthRequest, r1h)
-		rr2, _ := http.NewRequest("GET", s.URL, nil)
-		rr2.Header.Set(HTTPHeaderAuthRequest, r2h)
-		go httpGet(rr1, &wg2)
-		go httpGet(rr2, &wg2)
+		go httpGet(r1, &wg2)
+		go httpGet(r2, &wg2)
 	}
 	wg2.Wait()
 }
@@ -283,10 +274,7 @@ func TestService_SPNEGOKRB_Upload(t *testing.T) {
 	r.Header.Set("Content-Type", bodyWriter.FormDataContentType())
 
 	cl := getClient()
-	cookieJar, _ := cookiejar.New(nil)
-	httpCl := http.DefaultClient
-	httpCl.Jar = cookieJar
-	spnegoCl := NewClient(cl, httpCl, "HTTP/host.test.gokrb5")
+	spnegoCl := NewClient(cl, nil, "HTTP/host.test.gokrb5")
 	httpResp, err := spnegoCl.Do(r)
 	if err != nil {
 		t.Fatalf("Request error: %v\n", err)
@@ -304,23 +292,13 @@ func httpGet(r *http.Request, wg *sync.WaitGroup) {
 	http.DefaultClient.Do(r)
 }
 
-func httpServerWithoutSessionManager() *httptest.Server {
-	l := log.New(os.Stderr, "GOKRB5 Service Tests: ", log.LstdFlags)
-	b, _ := hex.DecodeString(testdata.HTTP_KEYTAB)
-	kt := keytab.New()
-	kt.Unmarshal(b)
-	th := http.HandlerFunc(testAppHandler)
-	s := httptest.NewServer(SPNEGOKRB5Authenticate(th, kt, service.Logger(l)))
-	return s
-}
-
 func httpServer() *httptest.Server {
-	l := log.New(os.Stderr, "GOKRB5 Service Tests: ", log.LstdFlags)
+	l := log.New(os.Stderr, "GOKRB5 Service Tests: ", log.Ldate|log.Ltime|log.Lshortfile)
 	b, _ := hex.DecodeString(testdata.HTTP_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
 	th := http.HandlerFunc(testAppHandler)
-	s := httptest.NewServer(SPNEGOKRB5Authenticate(th, kt, service.Logger(l), service.SessionManager(NewSessionMgr("gokrb5"))))
+	s := httptest.NewServer(SPNEGOKRB5Authenticate(th, kt, service.Logger(l)))
 	return s
 }
 
@@ -347,10 +325,10 @@ func testAppHandler(w http.ResponseWriter, r *http.Request) {
 		}
 	}
 	w.WriteHeader(http.StatusOK)
-	id := goidentity.FromHTTPRequestContext(r)
+	ctx := r.Context()
 	fmt.Fprintf(w, "<html>\nTEST.GOKRB5 Handler\nAuthenticed user: %s\nUser's realm: %s\n</html>",
-		id.UserName(),
-		id.Domain())
+		ctx.Value(CTXKeyCredentials).(goidentity.Identity).UserName(),
+		ctx.Value(CTXKeyCredentials).(goidentity.Identity).Domain())
 	return
 }
 
@@ -358,7 +336,7 @@ func getClient() *client.Client {
 	b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt := keytab.New()
 	kt.Unmarshal(b)
-	c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
 	c.LibDefaults.NoAddresses = true
 	addr := os.Getenv("TEST_KDC_ADDR")
 	if addr == "" {
@@ -366,45 +344,6 @@ func getClient() *client.Client {
 	}
 	c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
 	c.Realms[0].KPasswdServer = []string{addr + ":464"}
-	cl := client.NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
+	cl := client.NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
 	return cl
 }
-
-type SessionMgr struct {
-	skey       []byte
-	store      sessions.Store
-	cookieName string
-}
-
-func NewSessionMgr(cookieName string) SessionMgr {
-	skey := []byte("thisistestsecret") // Best practice is to load this key from a secure location.
-	return SessionMgr{
-		skey:       skey,
-		store:      sessions.NewCookieStore(skey),
-		cookieName: cookieName,
-	}
-}
-
-func (smgr SessionMgr) Get(r *http.Request, k string) ([]byte, error) {
-	s, err := smgr.store.Get(r, smgr.cookieName)
-	if err != nil {
-		return nil, err
-	}
-	if s == nil {
-		return nil, errors.New("nil session")
-	}
-	b, ok := s.Values[k].([]byte)
-	if !ok {
-		return nil, fmt.Errorf("could not get bytes held in session at %s", k)
-	}
-	return b, nil
-}
-
-func (smgr SessionMgr) New(w http.ResponseWriter, r *http.Request, k string, v []byte) error {
-	s, err := smgr.store.New(r, smgr.cookieName)
-	if err != nil {
-		return fmt.Errorf("could not get new session from session manager: %v", err)
-	}
-	s.Values[k] = v
-	return s.Save(r, w)
-}
diff --git a/spnego/krb5Token_test.go b/spnego/krb5Token_test.go
index 92139dc..257316f 100644
--- a/spnego/krb5Token_test.go
+++ b/spnego/krb5Token_test.go
@@ -33,7 +33,7 @@ func TestKRB5Token_Unmarshal(t *testing.T) {
 	if err != nil {
 		t.Fatalf("Error unmarshalling KRB5Token: %v", err)
 	}
-	assert.Equal(t, gssapi.OIDKRB5.OID(), mt.OID, "KRB5Token OID not as expected.")
+	assert.Equal(t, gssapi.OID(gssapi.OIDKRB5), mt.OID, "KRB5Token OID not as expected.")
 	assert.Equal(t, []byte{1, 0}, mt.tokID, "TokID not as expected")
 	assert.Equal(t, msgtype.KRB_AP_REQ, mt.APReq.MsgType, "KRB5Token AP_REQ does not have the right message type.")
 	assert.Equal(t, int32(0), mt.KRBError.ErrorCode, "KRBError in KRB5Token does not indicate no error.")