Skip to content

Commit 79ddf8a

Browse files
committed
implemented
1 parent 2d321f5 commit 79ddf8a

2 files changed

Lines changed: 101 additions & 75 deletions

File tree

gateway/mw_auth_key.go

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ func (k *AuthKey) ProcessRequest(_ http.ResponseWriter, r *http.Request, _ inter
131131
}
132132
key = k.Gw.generateToken(k.Spec.OrgID, certHash)
133133
session, keyExists = k.CheckSessionAndIdentityForValidKey(key, r)
134+
if !keyExists {
135+
return errorAndStatusCode(ErrAuthCertMismatch)
136+
}
134137
} else {
135138
if key != "" {
136139
session, keyExists = k.CheckSessionAndIdentityForValidKey(key, r)
@@ -145,46 +148,15 @@ func (k *AuthKey) ProcessRequest(_ http.ResponseWriter, r *http.Request, _ inter
145148
}
146149
}
147150

148-
//if key != "" {
149-
// fmt.Println("key: ", key)
150-
// key = stripBearer(key)
151-
//} else if authConfig.UseCertificate && key == "" && r.TLS != nil && len(r.TLS.PeerCertificates) > 0 {
152-
// fmt.Println("Trying to find key by client certificate")
153-
// log.Debug("Trying to find key by client certificate")
154-
// certHash = k.Spec.OrgID + crypto.HexSHA256(r.TLS.PeerCertificates[0].Raw)
155-
// fmt.Println("certHash: ", certHash)
156-
// if time.Now().After(r.TLS.PeerCertificates[0].NotAfter) {
157-
// return errorAndStatusCode(ErrAuthCertExpired)
158-
// }
159-
//
160-
// key = k.Gw.generateToken(k.Spec.OrgID, certHash)
161-
// fmt.Println("key: ", key)
162-
//} else {
163-
// k.Logger().Info("Attempted access with malformed header, no auth header found.")
164-
// return errorAndStatusCode(ErrAuthAuthorizationFieldMissing)
165-
//}
166-
//
167-
//session, keyExists = k.CheckSessionAndIdentityForValidKey(key, r)
168-
//key = session.KeyID
169-
//fmt.Printf("CheckSessionAndIdentityForValidKey: %s %v\n", key, keyExists)
170-
//if !keyExists {
171-
// // fallback to search by cert
172-
// session, keyExists = k.CheckSessionAndIdentityForValidKey(certHash, r)
173-
// fmt.Printf("CheckSessionAndIdentityForValidKey (cert hash): %s %v\n", certHash, keyExists)
174-
// if !keyExists {
175-
// return k.reportInvalidKey(key, r, MsgNonExistentKey, ErrAuthKeyNotFound)
176-
// }
177-
//}
178-
179151
if authConfig.UseCertificate {
180152
certLookup := session.Certificate
181153

182154
if r.TLS != nil && len(r.TLS.PeerCertificates) > 0 {
183155
certLookup = certHash
184-
//if session.Certificate != "" && session.Certificate != certHash {
185-
// // Certificate mismatch - provided certificate doesn't match the one in session
186-
// return errorAndStatusCode(ErrAuthCertMismatch)
187-
//}
156+
if session.Certificate != "" && session.Certificate != certHash {
157+
// Certificate mismatch - provided certificate doesn't match the one in session
158+
return errorAndStatusCode(ErrAuthCertMismatch)
159+
}
188160

189161
if session.Certificate != certHash {
190162
session.Certificate = certHash

gateway/mw_auth_key_test.go

Lines changed: 94 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ import (
44
"crypto/x509"
55
"encoding/hex"
66
"fmt"
7-
"github.com/TykTechnologies/tyk/internal/crypto"
87
"net/http"
98
"net/http/httptest"
109
"net/url"
1110
"testing"
1211
"time"
1312

13+
"github.com/TykTechnologies/tyk/internal/crypto"
14+
1415
"github.com/justinas/alice"
1516
"github.com/stretchr/testify/assert"
1617

@@ -198,7 +199,7 @@ func TestSignatureValidation(t *testing.T) {
198199
ts.Gw.LoadAPI(api)
199200

200201
key := CreateSession(ts.Gw, func(s *user.SessionState) {
201-
s.MetaData = map[string]interface{}{
202+
s.MetaData = map[string]any{
202203
"signature_secret": "foobar",
203204
}
204205
})
@@ -240,7 +241,7 @@ func TestSignatureValidation(t *testing.T) {
240241
session.AccessRights = map[string]user.AccessDefinition{"test": {
241242
APIID: "test", Versions: []string{"v1"},
242243
}}
243-
session.MetaData = map[string]interface{}{
244+
session.MetaData = map[string]any{
244245
"signature_secret": secret,
245246
}
246247

@@ -394,7 +395,7 @@ func BenchmarkBearerTokenAuthKeySession(b *testing.B) {
394395

395396
chain := getAuthKeyChain(spec, ts)
396397

397-
for i := 0; i < b.N; i++ {
398+
for b.Loop() {
398399
chain.ServeHTTP(recorder, req)
399400
if recorder.Code != 200 {
400401
b.Error("Initial request failed with non-200 code, should have gone through!: \n", recorder.Code)
@@ -454,7 +455,7 @@ func BenchmarkMultiAuthBackwardsCompatibleSession(b *testing.B) {
454455

455456
chain := getAuthKeyChain(spec, ts)
456457

457-
for i := 0; i < b.N; i++ {
458+
for b.Loop() {
458459
chain.ServeHTTP(recorder, req)
459460
if recorder.Code != 200 {
460461
b.Error("Initial request failed with non-200 code, should have gone through!: \n", recorder.Code)
@@ -591,12 +592,96 @@ func TestStripBearer(t *testing.T) {
591592
func BenchmarkStripBearer(b *testing.B) {
592593
b.ReportAllocs()
593594

594-
for i := 0; i < b.N; i++ {
595+
for b.Loop() {
595596
_ = stripBearer("Bearer abcdefghijklmnopqrstuvwxyz12345678910")
596597
}
597598
}
598599

599-
func TestDynamicMTLS(t *testing.T) {
600+
func TestDynamicMTLSInsecure(t *testing.T) {
601+
serverCertPem, _, combinedPEM, _ := certs.GenServerCertificate()
602+
certID, _, _ := certs.GetCertIDAndChainPEM(combinedPEM, "")
603+
604+
conf := func(globalConf *config.Config) {
605+
globalConf.Security.ControlAPIUseMutualTLS = false
606+
globalConf.Security.AllowUnsafeDynamicMTLSToken = true // Insecure behavior for this test
607+
globalConf.HttpServerOptions.UseSSL = true
608+
globalConf.HttpServerOptions.SSLInsecureSkipVerify = true
609+
globalConf.HttpServerOptions.SSLCertificates = []string{"default" + certID}
610+
}
611+
ts := StartTest(conf)
612+
defer ts.Close()
613+
614+
certID, err := ts.Gw.CertificateManager.Add(combinedPEM, "default")
615+
assert.NoError(t, err)
616+
defer ts.Gw.CertificateManager.Delete(certID, "default")
617+
ts.ReloadGatewayProxy()
618+
619+
ts.Gw.BuildAndLoadAPI(func(spec *APISpec) {
620+
spec.APIID = "apiID-1"
621+
spec.UseStandardAuth = true
622+
spec.UseKeylessAccess = false
623+
authConf := apidef.AuthConfig{
624+
Name: "authToken",
625+
UseCertificate: true,
626+
AuthHeaderName: "Authorization",
627+
}
628+
spec.AuthConfigs = map[string]apidef.AuthConfig{
629+
"authToken": authConf,
630+
}
631+
spec.Auth = authConf
632+
spec.Proxy.ListenPath = "/dynamic-mtls"
633+
})
634+
635+
// Initialize client certificates
636+
clientCertPem, _, _, clientCert := certs.GenCertificate(&x509.Certificate{}, false)
637+
638+
clientCertID, err := ts.Gw.CertificateManager.Add(clientCertPem, "default")
639+
assert.NoError(t, err)
640+
certHash := "default" + crypto.HexSHA256(clientCert.Certificate[0])
641+
642+
_, keyHash := ts.CreateSession(func(s *user.SessionState) {
643+
s.AccessRights = map[string]user.AccessDefinition{"apiID-1": {
644+
APIID: "apiID-1",
645+
}}
646+
s.Certificate = clientCertID
647+
})
648+
649+
t.Run("valid certificate provided", func(t *testing.T) {
650+
validCertClient := GetTLSClient(&clientCert, serverCertPem)
651+
_, _ = ts.Run(t, test.TestCase{
652+
Domain: "localhost",
653+
Client: validCertClient,
654+
Path: "/dynamic-mtls",
655+
Code: http.StatusOK,
656+
})
657+
})
658+
659+
t.Run("missing cert with generated cert hash and allow unsafe - should be accepted", func(t *testing.T) {
660+
certClient := GetTLSClient(nil, serverCertPem)
661+
_, _ = ts.Run(t, test.TestCase{
662+
Path: "/dynamic-mtls",
663+
Code: http.StatusOK,
664+
Client: certClient,
665+
Headers: map[string]string{
666+
"Authorization": certHash,
667+
},
668+
})
669+
})
670+
671+
t.Run("missing cert with generated key and allow unsafe - should be accepted", func(t *testing.T) {
672+
certClient := GetTLSClient(nil, serverCertPem)
673+
_, _ = ts.Run(t, test.TestCase{
674+
Path: "/dynamic-mtls",
675+
Code: http.StatusOK,
676+
Client: certClient,
677+
Headers: map[string]string{
678+
"Authorization": keyHash,
679+
},
680+
})
681+
})
682+
}
683+
684+
func TestDynamicMTLSSecure(t *testing.T) {
600685
serverCertPem, _, combinedPEM, _ := certs.GenServerCertificate()
601686
certID, _, _ := certs.GetCertIDAndChainPEM(combinedPEM, "")
602687

@@ -679,7 +764,7 @@ func TestDynamicMTLS(t *testing.T) {
679764
})
680765
})
681766

682-
t.Run("missing cert with generated cert - should be rejected by default", func(t *testing.T) {
767+
t.Run("missing cert with generated cert hash - should be rejected by default", func(t *testing.T) {
683768
certClient := GetTLSClient(nil, serverCertPem)
684769
_, _ = ts.Run(t, test.TestCase{
685770
Path: "/dynamic-mtls",
@@ -708,7 +793,6 @@ func TestDynamicMTLS(t *testing.T) {
708793
})
709794
})
710795

711-
// KOFO: you are here, trying to make this test pass by rejecting the request if the certificate does not match
712796
t.Run("non-matching certificate - should be rejected", func(t *testing.T) {
713797
differentClientPem, _, _, differentClientCert := certs.GenCertificate(&x509.Certificate{}, false)
714798
_, err := ts.Gw.CertificateManager.Add(differentClientPem, "default")
@@ -718,38 +802,8 @@ func TestDynamicMTLS(t *testing.T) {
718802
_, _ = ts.Run(t, test.TestCase{
719803
Client: differentCertClient,
720804
Path: "/dynamic-mtls",
721-
Code: http.StatusForbidden,
805+
Code: http.StatusUnauthorized,
722806
BodyMatch: MsgApiAccessDisallowed,
723807
})
724808
})
725-
726-
t.Run("with AllowUnsafeDynamicMTLSToken=true", func(t *testing.T) {
727-
// Change the configuration to allow token auth without certificates
728-
gatewayConfig := ts.Gw.GetConfig()
729-
gatewayConfig.Security.AllowUnsafeDynamicMTLSToken = true
730-
ts.Gw.SetConfig(gatewayConfig)
731-
ts.ReloadGatewayProxy()
732-
733-
// Create a new token for testing with the relaxed setting
734-
tokenID := CreateSession(ts.Gw, func(s *user.SessionState) {
735-
s.AccessRights = map[string]user.AccessDefinition{"apiID-1": {
736-
APIID: "apiID-1",
737-
}}
738-
})
739-
740-
// Test without certificate - should succeed with relaxed setting
741-
_, _ = ts.Run(t, test.TestCase{
742-
Headers: map[string]string{
743-
"Authorization": tokenID,
744-
},
745-
Path: "/dynamic-mtls",
746-
Code: http.StatusOK,
747-
})
748-
749-
// Reset back to secure mode
750-
gatewayConfig = ts.Gw.GetConfig()
751-
gatewayConfig.Security.AllowUnsafeDynamicMTLSToken = false
752-
ts.Gw.SetConfig(gatewayConfig)
753-
ts.ReloadGatewayProxy()
754-
})
755809
}

0 commit comments

Comments
 (0)