go.mod: github.com/Azure/go-autorest/autorest v0.11.24
Update the indirect dependency to remove the transitional github.com/form3tech-oss/jwt-go
dependency from the dependency graph.
Updates:
- github.com/Azure/go-autorest/autorest v0.11.24: https://github.com/Azure/go-autorest/compare/autorest/v0.11.20...autorest/v0.11.24
- github.com/Azure/go-autorest/autorest/adal v0.9.18: https://github.com/Azure/go-autorest/compare/autorest/adal/v0.9.15...autorest/adal/v0.9.18
- github.com/golang-jwt/jwt v4.2.0: https://github.com/golang-jwt/jwt/compare/v4.0.0...v4.2.0
- golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3: 32db794688...e495a2d5b3
Before this:
    go mod graph | grep 'jwt'
    github.com/Azure/go-autorest/autorest/adal@v0.9.15 github.com/golang-jwt/jwt/v4@v4.0.0
    github.com/Azure/go-autorest/autorest/adal@v0.9.13 github.com/form3tech-oss/jwt-go@v3.2.2+incompatible
After this:
    go mod graph | grep 'jwt'
    github.com/Azure/go-autorest/autorest@v0.11.24 github.com/golang-jwt/jwt/v4@v4.2.0
    github.com/Azure/go-autorest/autorest/adal@v0.9.18 github.com/golang-jwt/jwt/v4@v4.0.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
			
			
				master
			
			
		
							parent
							
								
									be4c921514
								
							
						
					
					
						commit
						4f1c1e4268
					
				
							
								
								
									
										5
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										5
									
								
								go.mod
								
								
								
								
							|  | @ -4,8 +4,7 @@ go 1.16 | ||||||
| 
 | 
 | ||||||
| require ( | require ( | ||||||
| 	github.com/Azure/azure-sdk-for-go v56.3.0+incompatible | 	github.com/Azure/azure-sdk-for-go v56.3.0+incompatible | ||||||
| 	github.com/Azure/go-autorest/autorest v0.11.20 // indirect | 	github.com/Azure/go-autorest/autorest v0.11.24 // indirect | ||||||
| 	github.com/Azure/go-autorest/autorest/adal v0.9.15 // indirect |  | ||||||
| 	github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect | 	github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect | ||||||
| 	github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d | 	github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d | ||||||
| 	github.com/aws/aws-sdk-go v1.42.27 | 	github.com/aws/aws-sdk-go v1.42.27 | ||||||
|  | @ -33,7 +32,7 @@ require ( | ||||||
| 	github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 // indirect | 	github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 // indirect | ||||||
| 	github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 | 	github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 | ||||||
| 	github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f // indirect | 	github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f // indirect | ||||||
| 	golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 | 	golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 | ||||||
| 	golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 | 	golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 | ||||||
| 	google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff | 	google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff | ||||||
| 	// when updating google.golang.org/cloud, update (or remove) the replace | 	// when updating google.golang.org/cloud, update (or remove) the replace | ||||||
|  |  | ||||||
							
								
								
									
										22
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										22
									
								
								go.sum
								
								
								
								
							|  | @ -4,11 +4,10 @@ github.com/Azure/azure-sdk-for-go v56.3.0+incompatible h1:DmhwMrUIvpeoTDiWRDtNHq | ||||||
| github.com/Azure/azure-sdk-for-go v56.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= | github.com/Azure/azure-sdk-for-go v56.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= | ||||||
| github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= | github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= | ||||||
| github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= | github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= | ||||||
| github.com/Azure/go-autorest/autorest v0.11.20 h1:s8H1PbCZSqg/DH7JMlOz6YMig6htWLNPsjDdlLqCx3M= | github.com/Azure/go-autorest/autorest v0.11.24 h1:1fIGgHKqVm54KIPT+q8Zmd1QlVsmHqeUGso5qm2BqqE= | ||||||
| github.com/Azure/go-autorest/autorest v0.11.20/go.mod h1:o3tqFY+QR40VOlk+pV4d77mORO64jOXSgEnPQgLK6JY= | github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= | ||||||
| github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= | github.com/Azure/go-autorest/autorest/adal v0.9.18 h1:kLnPsRjzZZUF3K5REu/Kc+qMQrvuza2bwSnNdhmzLfQ= | ||||||
| github.com/Azure/go-autorest/autorest/adal v0.9.15 h1:X+p2GF0GWyOiSmqohIaEeuNFNDY4I4EOlVuUQvFdWMk= | github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= | ||||||
| github.com/Azure/go-autorest/autorest/adal v0.9.15/go.mod h1:tGMin8I49Yij6AQ+rvV+Xa/zwxYQB5hmsd6DkfAx2+A= |  | ||||||
| github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= | github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= | ||||||
| github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= | github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= | ||||||
| github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk= | github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk= | ||||||
|  | @ -65,7 +64,6 @@ github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arX | ||||||
| github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= | github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= | ||||||
| github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= | github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= | ||||||
| github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= | github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= | ||||||
| github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= |  | ||||||
| github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= | ||||||
| github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= | ||||||
| github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= | ||||||
|  | @ -76,8 +74,9 @@ github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPh | ||||||
| github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= | github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= | ||||||
| github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= | ||||||
| github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= | github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= | ||||||
| github.com/golang-jwt/jwt/v4 v4.0.0 h1:RAqyYixv1p7uEnocuy8P1nru5wprCh/MH2BIlW5z5/o= |  | ||||||
| github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= | github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= | ||||||
|  | github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU= | ||||||
|  | github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= | ||||||
| github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= | ||||||
| github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | ||||||
| github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||||
|  | @ -199,17 +198,17 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ | ||||||
| go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= | go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= | ||||||
| golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||||
| golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | ||||||
| golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= | golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= | ||||||
| golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= | ||||||
| golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||||
| golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||||
| golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||||
| golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||||
| golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= |  | ||||||
| golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= | golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= | ||||||
| golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||||
| golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||||
|  | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||||
| golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM= | golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM= | ||||||
| golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||||
| golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= | ||||||
|  | @ -220,7 +219,6 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h | ||||||
| golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
| golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
| golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
| golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |  | ||||||
| golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
|  |  | ||||||
|  | @ -9,5 +9,5 @@ require ( | ||||||
| 	github.com/Azure/go-autorest/logger v0.2.1 | 	github.com/Azure/go-autorest/logger v0.2.1 | ||||||
| 	github.com/Azure/go-autorest/tracing v0.6.0 | 	github.com/Azure/go-autorest/tracing v0.6.0 | ||||||
| 	github.com/golang-jwt/jwt/v4 v4.0.0 | 	github.com/golang-jwt/jwt/v4 v4.0.0 | ||||||
| 	golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 | 	golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | @ -10,10 +10,11 @@ github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUM | ||||||
| github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= | github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= | ||||||
| github.com/golang-jwt/jwt/v4 v4.0.0 h1:RAqyYixv1p7uEnocuy8P1nru5wprCh/MH2BIlW5z5/o= | github.com/golang-jwt/jwt/v4 v4.0.0 h1:RAqyYixv1p7uEnocuy8P1nru5wprCh/MH2BIlW5z5/o= | ||||||
| github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= | github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= | ||||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= | ||||||
| golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE= | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | ||||||
| golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||||
| golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
| golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||||
|  | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||||
|  |  | ||||||
|  | @ -16,9 +16,11 @@ package adal | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"crypto/tls" | 	"crypto/tls" | ||||||
|  | 	"net" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/http/cookiejar" | 	"net/http/cookiejar" | ||||||
| 	"sync" | 	"sync" | ||||||
|  | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Azure/go-autorest/tracing" | 	"github.com/Azure/go-autorest/tracing" | ||||||
| ) | ) | ||||||
|  | @ -72,15 +74,18 @@ func sender() Sender { | ||||||
| 	// note that we can't init defaultSender in init() since it will
 | 	// note that we can't init defaultSender in init() since it will
 | ||||||
| 	// execute before calling code has had a chance to enable tracing
 | 	// execute before calling code has had a chance to enable tracing
 | ||||||
| 	defaultSenderInit.Do(func() { | 	defaultSenderInit.Do(func() { | ||||||
| 		// Use behaviour compatible with DefaultTransport, but require TLS minimum version.
 | 		// copied from http.DefaultTransport with a TLS minimum version.
 | ||||||
| 		defaultTransport := http.DefaultTransport.(*http.Transport) |  | ||||||
| 		transport := &http.Transport{ | 		transport := &http.Transport{ | ||||||
| 			Proxy:                 defaultTransport.Proxy, | 			Proxy: http.ProxyFromEnvironment, | ||||||
| 			DialContext:           defaultTransport.DialContext, | 			DialContext: (&net.Dialer{ | ||||||
| 			MaxIdleConns:          defaultTransport.MaxIdleConns, | 				Timeout:   30 * time.Second, | ||||||
| 			IdleConnTimeout:       defaultTransport.IdleConnTimeout, | 				KeepAlive: 30 * time.Second, | ||||||
| 			TLSHandshakeTimeout:   defaultTransport.TLSHandshakeTimeout, | 			}).DialContext, | ||||||
| 			ExpectContinueTimeout: defaultTransport.ExpectContinueTimeout, | 			ForceAttemptHTTP2:     true, | ||||||
|  | 			MaxIdleConns:          100, | ||||||
|  | 			IdleConnTimeout:       90 * time.Second, | ||||||
|  | 			TLSHandshakeTimeout:   10 * time.Second, | ||||||
|  | 			ExpectContinueTimeout: 1 * time.Second, | ||||||
| 			TLSClientConfig: &tls.Config{ | 			TLSClientConfig: &tls.Config{ | ||||||
| 				MinVersion: tls.VersionTLS12, | 				MinVersion: tls.VersionTLS12, | ||||||
| 			}, | 			}, | ||||||
|  |  | ||||||
|  | @ -676,8 +676,6 @@ const ( | ||||||
| 
 | 
 | ||||||
| func (m msiType) String() string { | func (m msiType) String() string { | ||||||
| 	switch m { | 	switch m { | ||||||
| 	case msiTypeUnavailable: |  | ||||||
| 		return "unavailable" |  | ||||||
| 	case msiTypeAppServiceV20170901: | 	case msiTypeAppServiceV20170901: | ||||||
| 		return "AppServiceV20170901" | 		return "AppServiceV20170901" | ||||||
| 	case msiTypeCloudShell: | 	case msiTypeCloudShell: | ||||||
|  | @ -699,13 +697,9 @@ func getMSIType() (msiType, string, error) { | ||||||
| 		} | 		} | ||||||
| 		// if ONLY the env var MSI_ENDPOINT is set the msiType is CloudShell
 | 		// if ONLY the env var MSI_ENDPOINT is set the msiType is CloudShell
 | ||||||
| 		return msiTypeCloudShell, endpointEnvVar, nil | 		return msiTypeCloudShell, endpointEnvVar, nil | ||||||
| 	} else if msiAvailableHook(context.Background(), sender()) { |  | ||||||
| 		// if MSI_ENDPOINT is NOT set AND the IMDS endpoint is available the msiType is IMDS. This will timeout after 500 milliseconds
 |  | ||||||
| 		return msiTypeIMDS, msiEndpoint, nil |  | ||||||
| 	} else { |  | ||||||
| 		// if MSI_ENDPOINT is NOT set and IMDS endpoint is not available Managed Identity is not available
 |  | ||||||
| 		return msiTypeUnavailable, "", errors.New("MSI not available") |  | ||||||
| 	} | 	} | ||||||
|  | 	// if MSI_ENDPOINT is NOT set assume the msiType is IMDS
 | ||||||
|  | 	return msiTypeIMDS, msiEndpoint, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetMSIVMEndpoint gets the MSI endpoint on Virtual Machines.
 | // GetMSIVMEndpoint gets the MSI endpoint on Virtual Machines.
 | ||||||
|  | @ -1322,15 +1316,13 @@ func NewMultiTenantServicePrincipalTokenFromCertificate(multiTenantCfg MultiTena | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // MSIAvailable returns true if the MSI endpoint is available for authentication.
 | // MSIAvailable returns true if the MSI endpoint is available for authentication.
 | ||||||
| func MSIAvailable(ctx context.Context, sender Sender) bool { | func MSIAvailable(ctx context.Context, s Sender) bool { | ||||||
| 	resp, err := getMSIEndpoint(ctx, sender) | 	if s == nil { | ||||||
|  | 		s = sender() | ||||||
|  | 	} | ||||||
|  | 	resp, err := getMSIEndpoint(ctx, s) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		resp.Body.Close() | 		resp.Body.Close() | ||||||
| 	} | 	} | ||||||
| 	return err == nil | 	return err == nil | ||||||
| } | } | ||||||
| 
 |  | ||||||
| // used for testing purposes
 |  | ||||||
| var msiAvailableHook = func(ctx context.Context, sender Sender) bool { |  | ||||||
| 	return MSIAvailable(ctx, sender) |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  | @ -25,7 +25,7 @@ import ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func getMSIEndpoint(ctx context.Context, sender Sender) (*http.Response, error) { | func getMSIEndpoint(ctx context.Context, sender Sender) (*http.Response, error) { | ||||||
| 	tempCtx, cancel := context.WithTimeout(ctx, 500*time.Millisecond) | 	tempCtx, cancel := context.WithTimeout(ctx, 2*time.Second) | ||||||
| 	defer cancel() | 	defer cancel() | ||||||
| 	// http.NewRequestWithContext() was added in Go 1.13
 | 	// http.NewRequestWithContext() was added in Go 1.13
 | ||||||
| 	req, _ := http.NewRequestWithContext(tempCtx, http.MethodGet, msiEndpoint, nil) | 	req, _ := http.NewRequestWithContext(tempCtx, http.MethodGet, msiEndpoint, nil) | ||||||
|  |  | ||||||
|  | @ -24,7 +24,7 @@ import ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func getMSIEndpoint(ctx context.Context, sender Sender) (*http.Response, error) { | func getMSIEndpoint(ctx context.Context, sender Sender) (*http.Response, error) { | ||||||
| 	tempCtx, cancel := context.WithTimeout(ctx, 500*time.Millisecond) | 	tempCtx, cancel := context.WithTimeout(ctx, 2*time.Second) | ||||||
| 	defer cancel() | 	defer cancel() | ||||||
| 	req, _ := http.NewRequest(http.MethodGet, msiEndpoint, nil) | 	req, _ := http.NewRequest(http.MethodGet, msiEndpoint, nil) | ||||||
| 	req = req.WithContext(tempCtx) | 	req = req.WithContext(tempCtx) | ||||||
|  |  | ||||||
|  | @ -68,7 +68,7 @@ func (se ServiceError) Error() string { | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			result += fmt.Sprintf(" Details=%v", se.Details) | 			result += fmt.Sprintf(" Details=%v", se.Details) | ||||||
| 		} | 		} | ||||||
| 		result += fmt.Sprintf(" Details=%v", string(d)) | 		result += fmt.Sprintf(" Details=%s", d) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if se.InnerError != nil { | 	if se.InnerError != nil { | ||||||
|  | @ -76,7 +76,7 @@ func (se ServiceError) Error() string { | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			result += fmt.Sprintf(" InnerError=%v", se.InnerError) | 			result += fmt.Sprintf(" InnerError=%v", se.InnerError) | ||||||
| 		} | 		} | ||||||
| 		result += fmt.Sprintf(" InnerError=%v", string(d)) | 		result += fmt.Sprintf(" InnerError=%s", d) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if se.AdditionalInfo != nil { | 	if se.AdditionalInfo != nil { | ||||||
|  | @ -84,7 +84,7 @@ func (se ServiceError) Error() string { | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			result += fmt.Sprintf(" AdditionalInfo=%v", se.AdditionalInfo) | 			result += fmt.Sprintf(" AdditionalInfo=%v", se.AdditionalInfo) | ||||||
| 		} | 		} | ||||||
| 		result += fmt.Sprintf(" AdditionalInfo=%v", string(d)) | 		result += fmt.Sprintf(" AdditionalInfo=%s", d) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return result | 	return result | ||||||
|  | @ -335,13 +335,13 @@ func WithErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator { | ||||||
| 				b, decodeErr := autorest.CopyAndDecode(encodedAs, resp.Body, &e) | 				b, decodeErr := autorest.CopyAndDecode(encodedAs, resp.Body, &e) | ||||||
| 				resp.Body = ioutil.NopCloser(&b) | 				resp.Body = ioutil.NopCloser(&b) | ||||||
| 				if decodeErr != nil { | 				if decodeErr != nil { | ||||||
| 					return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), decodeErr) | 					return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b, decodeErr) | ||||||
| 				} | 				} | ||||||
| 				if e.ServiceError == nil { | 				if e.ServiceError == nil { | ||||||
| 					// Check if error is unwrapped ServiceError
 | 					// Check if error is unwrapped ServiceError
 | ||||||
| 					decoder := autorest.NewDecoder(encodedAs, bytes.NewReader(b.Bytes())) | 					decoder := autorest.NewDecoder(encodedAs, bytes.NewReader(b.Bytes())) | ||||||
| 					if err := decoder.Decode(&e.ServiceError); err != nil { | 					if err := decoder.Decode(&e.ServiceError); err != nil { | ||||||
| 						return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), err) | 						return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b, err) | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					// for example, should the API return the literal value `null` as the response
 | 					// for example, should the API return the literal value `null` as the response
 | ||||||
|  | @ -364,7 +364,7 @@ func WithErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator { | ||||||
| 					rawBody := map[string]interface{}{} | 					rawBody := map[string]interface{}{} | ||||||
| 					decoder := autorest.NewDecoder(encodedAs, bytes.NewReader(b.Bytes())) | 					decoder := autorest.NewDecoder(encodedAs, bytes.NewReader(b.Bytes())) | ||||||
| 					if err := decoder.Decode(&rawBody); err != nil { | 					if err := decoder.Decode(&rawBody); err != nil { | ||||||
| 						return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), err) | 						return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b, err) | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					e.ServiceError = &ServiceError{ | 					e.ServiceError = &ServiceError{ | ||||||
|  |  | ||||||
|  | @ -49,6 +49,8 @@ type ResourceIdentifier struct { | ||||||
| 	Storage             string `json:"storage"` | 	Storage             string `json:"storage"` | ||||||
| 	Synapse             string `json:"synapse"` | 	Synapse             string `json:"synapse"` | ||||||
| 	ServiceBus          string `json:"serviceBus"` | 	ServiceBus          string `json:"serviceBus"` | ||||||
|  | 	SQLDatabase         string `json:"sqlDatabase"` | ||||||
|  | 	CosmosDB            string `json:"cosmosDB"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Environment represents a set of endpoints for each of Azure's Clouds.
 | // Environment represents a set of endpoints for each of Azure's Clouds.
 | ||||||
|  | @ -121,6 +123,8 @@ var ( | ||||||
| 			Storage:             "https://storage.azure.com/", | 			Storage:             "https://storage.azure.com/", | ||||||
| 			Synapse:             "https://dev.azuresynapse.net", | 			Synapse:             "https://dev.azuresynapse.net", | ||||||
| 			ServiceBus:          "https://servicebus.azure.net/", | 			ServiceBus:          "https://servicebus.azure.net/", | ||||||
|  | 			SQLDatabase:         "https://database.windows.net/", | ||||||
|  | 			CosmosDB:            "https://cosmos.azure.com", | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -162,6 +166,8 @@ var ( | ||||||
| 			Storage:             "https://storage.azure.com/", | 			Storage:             "https://storage.azure.com/", | ||||||
| 			Synapse:             NotAvailable, | 			Synapse:             NotAvailable, | ||||||
| 			ServiceBus:          "https://servicebus.azure.net/", | 			ServiceBus:          "https://servicebus.azure.net/", | ||||||
|  | 			SQLDatabase:         "https://database.usgovcloudapi.net/", | ||||||
|  | 			CosmosDB:            "https://cosmos.azure.com", | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -203,6 +209,8 @@ var ( | ||||||
| 			Storage:             "https://storage.azure.com/", | 			Storage:             "https://storage.azure.com/", | ||||||
| 			Synapse:             "https://dev.azuresynapse.net", | 			Synapse:             "https://dev.azuresynapse.net", | ||||||
| 			ServiceBus:          "https://servicebus.azure.net/", | 			ServiceBus:          "https://servicebus.azure.net/", | ||||||
|  | 			SQLDatabase:         "https://database.chinacloudapi.cn/", | ||||||
|  | 			CosmosDB:            "https://cosmos.azure.com", | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -244,6 +252,8 @@ var ( | ||||||
| 			Storage:             "https://storage.azure.com/", | 			Storage:             "https://storage.azure.com/", | ||||||
| 			Synapse:             NotAvailable, | 			Synapse:             NotAvailable, | ||||||
| 			ServiceBus:          "https://servicebus.azure.net/", | 			ServiceBus:          "https://servicebus.azure.net/", | ||||||
|  | 			SQLDatabase:         "https://database.cloudapi.de/", | ||||||
|  | 			CosmosDB:            "https://cosmos.azure.com", | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | @ -4,9 +4,10 @@ go 1.15 | ||||||
| 
 | 
 | ||||||
| require ( | require ( | ||||||
| 	github.com/Azure/go-autorest v14.2.0+incompatible | 	github.com/Azure/go-autorest v14.2.0+incompatible | ||||||
| 	github.com/Azure/go-autorest/autorest/adal v0.9.13 | 	github.com/Azure/go-autorest/autorest/adal v0.9.18 | ||||||
| 	github.com/Azure/go-autorest/autorest/mocks v0.4.1 | 	github.com/Azure/go-autorest/autorest/mocks v0.4.1 | ||||||
| 	github.com/Azure/go-autorest/logger v0.2.1 | 	github.com/Azure/go-autorest/logger v0.2.1 | ||||||
| 	github.com/Azure/go-autorest/tracing v0.6.0 | 	github.com/Azure/go-autorest/tracing v0.6.0 | ||||||
| 	golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 | 	github.com/golang-jwt/jwt/v4 v4.2.0 // indirect | ||||||
|  | 	golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= | github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= | ||||||
| github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= | github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= | ||||||
| github.com/Azure/go-autorest/autorest/adal v0.9.13 h1:Mp5hbtOePIzM8pJVRa3YLrWWmZtoxRXqUEzCfJt3+/Q= | github.com/Azure/go-autorest/autorest/adal v0.9.18 h1:kLnPsRjzZZUF3K5REu/Kc+qMQrvuza2bwSnNdhmzLfQ= | ||||||
| github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= | github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= | ||||||
| github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= | github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= | ||||||
| github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= | github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= | ||||||
| github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk= | github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk= | ||||||
|  | @ -10,14 +10,18 @@ github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+Z | ||||||
| github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= | github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= | ||||||
| github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= | github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= | ||||||
| github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= | github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= | ||||||
| github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk= | github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= | ||||||
| github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= | github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU= | ||||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= | github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= | ||||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | ||||||
| golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE= | golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= | ||||||
| golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= | ||||||
| golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||||
| golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||||
| golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
|  | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||||
|  | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||||
|  | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||||
|  | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||||
|  |  | ||||||
|  | @ -241,6 +241,8 @@ func WithBaseURL(baseURL string) PrepareDecorator { | ||||||
| 					return r, fmt.Errorf("autorest: No scheme detected in URL %s", baseURL) | 					return r, fmt.Errorf("autorest: No scheme detected in URL %s", baseURL) | ||||||
| 				} | 				} | ||||||
| 				if u.RawQuery != "" { | 				if u.RawQuery != "" { | ||||||
|  | 					// handle unencoded semicolons (ideally the server would send them already encoded)
 | ||||||
|  | 					u.RawQuery = strings.Replace(u.RawQuery, ";", "%3B", -1) | ||||||
| 					q, err := url.ParseQuery(u.RawQuery) | 					q, err := url.ParseQuery(u.RawQuery) | ||||||
| 					if err != nil { | 					if err != nil { | ||||||
| 						return r, err | 						return r, err | ||||||
|  |  | ||||||
|  | @ -20,6 +20,7 @@ import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"log" | 	"log" | ||||||
| 	"math" | 	"math" | ||||||
|  | 	"net" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/http/cookiejar" | 	"net/http/cookiejar" | ||||||
| 	"strconv" | 	"strconv" | ||||||
|  | @ -129,15 +130,18 @@ func sender(renengotiation tls.RenegotiationSupport) Sender { | ||||||
| 	// note that we can't init defaultSenders in init() since it will
 | 	// note that we can't init defaultSenders in init() since it will
 | ||||||
| 	// execute before calling code has had a chance to enable tracing
 | 	// execute before calling code has had a chance to enable tracing
 | ||||||
| 	defaultSenders[renengotiation].init.Do(func() { | 	defaultSenders[renengotiation].init.Do(func() { | ||||||
| 		// Use behaviour compatible with DefaultTransport, but require TLS minimum version.
 | 		// copied from http.DefaultTransport with a TLS minimum version.
 | ||||||
| 		defaultTransport := http.DefaultTransport.(*http.Transport) |  | ||||||
| 		transport := &http.Transport{ | 		transport := &http.Transport{ | ||||||
| 			Proxy:                 defaultTransport.Proxy, | 			Proxy: http.ProxyFromEnvironment, | ||||||
| 			DialContext:           defaultTransport.DialContext, | 			DialContext: (&net.Dialer{ | ||||||
| 			MaxIdleConns:          defaultTransport.MaxIdleConns, | 				Timeout:   30 * time.Second, | ||||||
| 			IdleConnTimeout:       defaultTransport.IdleConnTimeout, | 				KeepAlive: 30 * time.Second, | ||||||
| 			TLSHandshakeTimeout:   defaultTransport.TLSHandshakeTimeout, | 			}).DialContext, | ||||||
| 			ExpectContinueTimeout: defaultTransport.ExpectContinueTimeout, | 			ForceAttemptHTTP2:     true, | ||||||
|  | 			MaxIdleConns:          100, | ||||||
|  | 			IdleConnTimeout:       90 * time.Second, | ||||||
|  | 			TLSHandshakeTimeout:   10 * time.Second, | ||||||
|  | 			ExpectContinueTimeout: 1 * time.Second, | ||||||
| 			TLSClientConfig: &tls.Config{ | 			TLSClientConfig: &tls.Config{ | ||||||
| 				MinVersion:    tls.VersionTLS12, | 				MinVersion:    tls.VersionTLS12, | ||||||
| 				Renegotiation: renengotiation, | 				Renegotiation: renengotiation, | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| ## Migration Guide (v4.0.0) | ## Migration Guide (v4.0.0) | ||||||
| 
 | 
 | ||||||
| Starting from [v4.0.0](https://github.com/golang-jwt/jwt/releases/tag/v4.0.0]), the import path will be: | Starting from [v4.0.0](https://github.com/golang-jwt/jwt/releases/tag/v4.0.0), the import path will be: | ||||||
| 
 | 
 | ||||||
|     "github.com/golang-jwt/jwt/v4" |     "github.com/golang-jwt/jwt/v4" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,12 +1,12 @@ | ||||||
| # jwt-go | # jwt-go | ||||||
| 
 | 
 | ||||||
| [](https://github.com/golang-jwt/jwt/actions/workflows/build.yml) | [](https://github.com/golang-jwt/jwt/actions/workflows/build.yml) | ||||||
| [](https://pkg.go.dev/github.com/golang-jwt/jwt) | [](https://pkg.go.dev/github.com/golang-jwt/jwt/v4) | ||||||
| 
 | 
 | ||||||
| A [go](http://www.golang.org) (or 'golang' for search engine friendliness) implementation of [JSON Web Tokens](https://datatracker.ietf.org/doc/html/rfc7519). | A [go](http://www.golang.org) (or 'golang' for search engine friendliness) implementation of [JSON Web Tokens](https://datatracker.ietf.org/doc/html/rfc7519). | ||||||
| 
 | 
 | ||||||
| Starting with [v4.0.0](https://github.com/golang-jwt/jwt/releases/tag/v4.0.0) this project adds Go module support, but maintains backwards compataibility with older `v3.x.y` tags and upstream `github.com/dgrijalva/jwt-go`. | Starting with [v4.0.0](https://github.com/golang-jwt/jwt/releases/tag/v4.0.0) this project adds Go module support, but maintains backwards compatibility with older `v3.x.y` tags and upstream `github.com/dgrijalva/jwt-go`. | ||||||
| See the `MIGRATION_GUIDE.md` for more information. | See the [`MIGRATION_GUIDE.md`](./MIGRATION_GUIDE.md) for more information. | ||||||
| 
 | 
 | ||||||
| > After the original author of the library suggested migrating the maintenance of `jwt-go`, a dedicated team of open source maintainers decided to clone the existing library into this repository. See [dgrijalva/jwt-go#462](https://github.com/dgrijalva/jwt-go/issues/462) for a detailed discussion on this topic. | > After the original author of the library suggested migrating the maintenance of `jwt-go`, a dedicated team of open source maintainers decided to clone the existing library into this repository. See [dgrijalva/jwt-go#462](https://github.com/dgrijalva/jwt-go/issues/462) for a detailed discussion on this topic. | ||||||
| 
 | 
 | ||||||
|  | @ -52,7 +52,7 @@ Here's an example of an extension that integrates with multiple Google Cloud Pla | ||||||
| 
 | 
 | ||||||
| ## Compliance | ## Compliance | ||||||
| 
 | 
 | ||||||
| This library was last reviewed to comply with [RTF 7519](https://datatracker.ietf.org/doc/html/rfc7519) dated May 2015 with a few notable differences: | This library was last reviewed to comply with [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519) dated May 2015 with a few notable differences: | ||||||
| 
 | 
 | ||||||
| * In order to protect against accidental use of [Unsecured JWTs](https://datatracker.ietf.org/doc/html/rfc7519#section-6), tokens using `alg=none` will only be accepted if the constant `jwt.UnsafeAllowNoneSignatureType` is provided as the key. | * In order to protect against accidental use of [Unsecured JWTs](https://datatracker.ietf.org/doc/html/rfc7519#section-6), tokens using `alg=none` will only be accepted if the constant `jwt.UnsafeAllowNoneSignatureType` is provided as the key. | ||||||
| 
 | 
 | ||||||
|  | @ -91,6 +91,7 @@ Each signing method expects a different object type for its signing keys. See th | ||||||
| * The [HMAC signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodHMAC) (`HS256`,`HS384`,`HS512`) expect `[]byte` values for signing and validation | * The [HMAC signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodHMAC) (`HS256`,`HS384`,`HS512`) expect `[]byte` values for signing and validation | ||||||
| * The [RSA signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodRSA) (`RS256`,`RS384`,`RS512`) expect `*rsa.PrivateKey` for signing and `*rsa.PublicKey` for validation | * The [RSA signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodRSA) (`RS256`,`RS384`,`RS512`) expect `*rsa.PrivateKey` for signing and `*rsa.PublicKey` for validation | ||||||
| * The [ECDSA signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodECDSA) (`ES256`,`ES384`,`ES512`) expect `*ecdsa.PrivateKey` for signing and `*ecdsa.PublicKey` for validation | * The [ECDSA signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodECDSA) (`ES256`,`ES384`,`ES512`) expect `*ecdsa.PrivateKey` for signing and `*ecdsa.PublicKey` for validation | ||||||
|  | * The [EdDSA signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodEd25519) (`Ed25519`) expect `ed25519.PrivateKey` for signing and `ed25519.PublicKey` for validation | ||||||
| 
 | 
 | ||||||
| ### JWT and OAuth | ### JWT and OAuth | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,9 +12,122 @@ type Claims interface { | ||||||
| 	Valid() error | 	Valid() error | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // StandardClaims are a structured version of the Claims Section, as referenced at
 | // RegisteredClaims are a structured version of the JWT Claims Set,
 | ||||||
| // https://tools.ietf.org/html/rfc7519#section-4.1
 | // restricted to Registered Claim Names, as referenced at
 | ||||||
| // See examples for how to use this with your own claim types
 | // https://datatracker.ietf.org/doc/html/rfc7519#section-4.1
 | ||||||
|  | //
 | ||||||
|  | // This type can be used on its own, but then additional private and
 | ||||||
|  | // public claims embedded in the JWT will not be parsed. The typical usecase
 | ||||||
|  | // therefore is to embedded this in a user-defined claim type.
 | ||||||
|  | //
 | ||||||
|  | // See examples for how to use this with your own claim types.
 | ||||||
|  | type RegisteredClaims struct { | ||||||
|  | 	// the `iss` (Issuer) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1
 | ||||||
|  | 	Issuer string `json:"iss,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// the `sub` (Subject) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.2
 | ||||||
|  | 	Subject string `json:"sub,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// the `aud` (Audience) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3
 | ||||||
|  | 	Audience ClaimStrings `json:"aud,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// the `exp` (Expiration Time) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4
 | ||||||
|  | 	ExpiresAt *NumericDate `json:"exp,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// the `nbf` (Not Before) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5
 | ||||||
|  | 	NotBefore *NumericDate `json:"nbf,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// the `iat` (Issued At) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6
 | ||||||
|  | 	IssuedAt *NumericDate `json:"iat,omitempty"` | ||||||
|  | 
 | ||||||
|  | 	// the `jti` (JWT ID) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.7
 | ||||||
|  | 	ID string `json:"jti,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Valid validates time based claims "exp, iat, nbf".
 | ||||||
|  | // There is no accounting for clock skew.
 | ||||||
|  | // As well, if any of the above claims are not in the token, it will still
 | ||||||
|  | // be considered a valid claim.
 | ||||||
|  | func (c RegisteredClaims) Valid() error { | ||||||
|  | 	vErr := new(ValidationError) | ||||||
|  | 	now := TimeFunc() | ||||||
|  | 
 | ||||||
|  | 	// The claims below are optional, by default, so if they are set to the
 | ||||||
|  | 	// default value in Go, let's not fail the verification for them.
 | ||||||
|  | 	if !c.VerifyExpiresAt(now, false) { | ||||||
|  | 		delta := now.Sub(c.ExpiresAt.Time) | ||||||
|  | 		vErr.Inner = fmt.Errorf("token is expired by %v", delta) | ||||||
|  | 		vErr.Errors |= ValidationErrorExpired | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if !c.VerifyIssuedAt(now, false) { | ||||||
|  | 		vErr.Inner = fmt.Errorf("token used before issued") | ||||||
|  | 		vErr.Errors |= ValidationErrorIssuedAt | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if !c.VerifyNotBefore(now, false) { | ||||||
|  | 		vErr.Inner = fmt.Errorf("token is not valid yet") | ||||||
|  | 		vErr.Errors |= ValidationErrorNotValidYet | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if vErr.valid() { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return vErr | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // VerifyAudience compares the aud claim against cmp.
 | ||||||
|  | // If required is false, this method will return true if the value matches or is unset
 | ||||||
|  | func (c *RegisteredClaims) VerifyAudience(cmp string, req bool) bool { | ||||||
|  | 	return verifyAud(c.Audience, cmp, req) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // VerifyExpiresAt compares the exp claim against cmp (cmp < exp).
 | ||||||
|  | // If req is false, it will return true, if exp is unset.
 | ||||||
|  | func (c *RegisteredClaims) VerifyExpiresAt(cmp time.Time, req bool) bool { | ||||||
|  | 	if c.ExpiresAt == nil { | ||||||
|  | 		return verifyExp(nil, cmp, req) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return verifyExp(&c.ExpiresAt.Time, cmp, req) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // VerifyIssuedAt compares the iat claim against cmp (cmp >= iat).
 | ||||||
|  | // If req is false, it will return true, if iat is unset.
 | ||||||
|  | func (c *RegisteredClaims) VerifyIssuedAt(cmp time.Time, req bool) bool { | ||||||
|  | 	if c.IssuedAt == nil { | ||||||
|  | 		return verifyIat(nil, cmp, req) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return verifyIat(&c.IssuedAt.Time, cmp, req) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // VerifyNotBefore compares the nbf claim against cmp (cmp >= nbf).
 | ||||||
|  | // If req is false, it will return true, if nbf is unset.
 | ||||||
|  | func (c *RegisteredClaims) VerifyNotBefore(cmp time.Time, req bool) bool { | ||||||
|  | 	if c.NotBefore == nil { | ||||||
|  | 		return verifyNbf(nil, cmp, req) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return verifyNbf(&c.NotBefore.Time, cmp, req) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // VerifyIssuer compares the iss claim against cmp.
 | ||||||
|  | // If required is false, this method will return true if the value matches or is unset
 | ||||||
|  | func (c *RegisteredClaims) VerifyIssuer(cmp string, req bool) bool { | ||||||
|  | 	return verifyIss(c.Issuer, cmp, req) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // StandardClaims are a structured version of the JWT Claims Set, as referenced at
 | ||||||
|  | // https://datatracker.ietf.org/doc/html/rfc7519#section-4. They do not follow the
 | ||||||
|  | // specification exactly, since they were based on an earlier draft of the
 | ||||||
|  | // specification and not updated. The main difference is that they only
 | ||||||
|  | // support integer-based date fields and singular audiences. This might lead to
 | ||||||
|  | // incompatibilities with other JWT implementations. The use of this is discouraged, instead
 | ||||||
|  | // the newer RegisteredClaims struct should be used.
 | ||||||
|  | //
 | ||||||
|  | // Deprecated: Use RegisteredClaims instead for a forward-compatible way to access registered claims in a struct.
 | ||||||
| type StandardClaims struct { | type StandardClaims struct { | ||||||
| 	Audience  string `json:"aud,omitempty"` | 	Audience  string `json:"aud,omitempty"` | ||||||
| 	ExpiresAt int64  `json:"exp,omitempty"` | 	ExpiresAt int64  `json:"exp,omitempty"` | ||||||
|  | @ -41,7 +154,7 @@ func (c StandardClaims) Valid() error { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if !c.VerifyIssuedAt(now, false) { | 	if !c.VerifyIssuedAt(now, false) { | ||||||
| 		vErr.Inner = fmt.Errorf("Token used before issued") | 		vErr.Inner = fmt.Errorf("token used before issued") | ||||||
| 		vErr.Errors |= ValidationErrorIssuedAt | 		vErr.Errors |= ValidationErrorIssuedAt | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -63,16 +176,37 @@ func (c *StandardClaims) VerifyAudience(cmp string, req bool) bool { | ||||||
| 	return verifyAud([]string{c.Audience}, cmp, req) | 	return verifyAud([]string{c.Audience}, cmp, req) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // VerifyExpiresAt compares the exp claim against cmp.
 | // VerifyExpiresAt compares the exp claim against cmp (cmp < exp).
 | ||||||
| // If required is false, this method will return true if the value matches or is unset
 | // If req is false, it will return true, if exp is unset.
 | ||||||
| func (c *StandardClaims) VerifyExpiresAt(cmp int64, req bool) bool { | func (c *StandardClaims) VerifyExpiresAt(cmp int64, req bool) bool { | ||||||
| 	return verifyExp(c.ExpiresAt, cmp, req) | 	if c.ExpiresAt == 0 { | ||||||
|  | 		return verifyExp(nil, time.Unix(cmp, 0), req) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	t := time.Unix(c.ExpiresAt, 0) | ||||||
|  | 	return verifyExp(&t, time.Unix(cmp, 0), req) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // VerifyIssuedAt compares the iat claim against cmp.
 | // VerifyIssuedAt compares the iat claim against cmp (cmp >= iat).
 | ||||||
| // If required is false, this method will return true if the value matches or is unset
 | // If req is false, it will return true, if iat is unset.
 | ||||||
| func (c *StandardClaims) VerifyIssuedAt(cmp int64, req bool) bool { | func (c *StandardClaims) VerifyIssuedAt(cmp int64, req bool) bool { | ||||||
| 	return verifyIat(c.IssuedAt, cmp, req) | 	if c.IssuedAt == 0 { | ||||||
|  | 		return verifyIat(nil, time.Unix(cmp, 0), req) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	t := time.Unix(c.IssuedAt, 0) | ||||||
|  | 	return verifyIat(&t, time.Unix(cmp, 0), req) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // VerifyNotBefore compares the nbf claim against cmp (cmp >= nbf).
 | ||||||
|  | // If req is false, it will return true, if nbf is unset.
 | ||||||
|  | func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool { | ||||||
|  | 	if c.NotBefore == 0 { | ||||||
|  | 		return verifyNbf(nil, time.Unix(cmp, 0), req) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	t := time.Unix(c.NotBefore, 0) | ||||||
|  | 	return verifyNbf(&t, time.Unix(cmp, 0), req) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // VerifyIssuer compares the iss claim against cmp.
 | // VerifyIssuer compares the iss claim against cmp.
 | ||||||
|  | @ -81,12 +215,6 @@ func (c *StandardClaims) VerifyIssuer(cmp string, req bool) bool { | ||||||
| 	return verifyIss(c.Issuer, cmp, req) | 	return verifyIss(c.Issuer, cmp, req) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // VerifyNotBefore compares the nbf claim against cmp.
 |  | ||||||
| // If required is false, this method will return true if the value matches or is unset
 |  | ||||||
| func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool { |  | ||||||
| 	return verifyNbf(c.NotBefore, cmp, req) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ----- helpers
 | // ----- helpers
 | ||||||
| 
 | 
 | ||||||
| func verifyAud(aud []string, cmp string, required bool) bool { | func verifyAud(aud []string, cmp string, required bool) bool { | ||||||
|  | @ -112,18 +240,25 @@ func verifyAud(aud []string, cmp string, required bool) bool { | ||||||
| 	return result | 	return result | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func verifyExp(exp int64, now int64, required bool) bool { | func verifyExp(exp *time.Time, now time.Time, required bool) bool { | ||||||
| 	if exp == 0 { | 	if exp == nil { | ||||||
| 		return !required | 		return !required | ||||||
| 	} | 	} | ||||||
| 	return now <= exp | 	return now.Before(*exp) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func verifyIat(iat int64, now int64, required bool) bool { | func verifyIat(iat *time.Time, now time.Time, required bool) bool { | ||||||
| 	if iat == 0 { | 	if iat == nil { | ||||||
| 		return !required | 		return !required | ||||||
| 	} | 	} | ||||||
| 	return now >= iat | 	return now.After(*iat) || now.Equal(*iat) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func verifyNbf(nbf *time.Time, now time.Time, required bool) bool { | ||||||
|  | 	if nbf == nil { | ||||||
|  | 		return !required | ||||||
|  | 	} | ||||||
|  | 	return now.After(*nbf) || now.Equal(*nbf) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func verifyIss(iss string, cmp string, required bool) bool { | func verifyIss(iss string, cmp string, required bool) bool { | ||||||
|  | @ -136,10 +271,3 @@ func verifyIss(iss string, cmp string, required bool) bool { | ||||||
| 		return false | 		return false | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 |  | ||||||
| func verifyNbf(nbf int64, now int64, required bool) bool { |  | ||||||
| 	if nbf == 0 { |  | ||||||
| 		return !required |  | ||||||
| 	} |  | ||||||
| 	return now >= nbf |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  | @ -3,7 +3,9 @@ package jwt | ||||||
| import ( | import ( | ||||||
| 	"errors" | 	"errors" | ||||||
| 
 | 
 | ||||||
|  | 	"crypto" | ||||||
| 	"crypto/ed25519" | 	"crypto/ed25519" | ||||||
|  | 	"crypto/rand" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
|  | @ -62,20 +64,22 @@ func (m *SigningMethodEd25519) Verify(signingString, signature string, key inter | ||||||
| // Sign implements token signing for the SigningMethod.
 | // Sign implements token signing for the SigningMethod.
 | ||||||
| // For this signing method, key must be an ed25519.PrivateKey
 | // For this signing method, key must be an ed25519.PrivateKey
 | ||||||
| func (m *SigningMethodEd25519) Sign(signingString string, key interface{}) (string, error) { | func (m *SigningMethodEd25519) Sign(signingString string, key interface{}) (string, error) { | ||||||
| 	var ed25519Key ed25519.PrivateKey | 	var ed25519Key crypto.Signer | ||||||
| 	var ok bool | 	var ok bool | ||||||
| 
 | 
 | ||||||
| 	if ed25519Key, ok = key.(ed25519.PrivateKey); !ok { | 	if ed25519Key, ok = key.(crypto.Signer); !ok { | ||||||
| 		return "", ErrInvalidKeyType | 		return "", ErrInvalidKeyType | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// ed25519.Sign panics if private key not equal to ed25519.PrivateKeySize
 | 	if _, ok := ed25519Key.Public().(ed25519.PublicKey); !ok { | ||||||
| 	// this allows to avoid recover usage
 |  | ||||||
| 	if len(ed25519Key) != ed25519.PrivateKeySize { |  | ||||||
| 		return "", ErrInvalidKey | 		return "", ErrInvalidKey | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Sign the string and return the encoded result
 | 	// Sign the string and return the encoded result
 | ||||||
| 	sig := ed25519.Sign(ed25519Key, []byte(signingString)) | 	// ed25519 performs a two-pass hash as part of its algorithm. Therefore, we need to pass a non-prehashed message into the Sign function, as indicated by crypto.Hash(0)
 | ||||||
|  | 	sig, err := ed25519Key.Sign(rand.Reader, []byte(signingString), crypto.Hash(0)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
| 	return EncodeSegment(sig), nil | 	return EncodeSegment(sig), nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -53,6 +53,11 @@ func (e ValidationError) Error() string { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Unwrap gives errors.Is and errors.As access to the inner error.
 | ||||||
|  | func (e *ValidationError) Unwrap() error { | ||||||
|  | 	return e.Inner | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // No errors
 | // No errors
 | ||||||
| func (e *ValidationError) valid() bool { | func (e *ValidationError) valid() bool { | ||||||
| 	return e.Errors == 0 | 	return e.Errors == 0 | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ package jwt | ||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"errors" | 	"errors" | ||||||
|  | 	"time" | ||||||
| 	// "fmt"
 | 	// "fmt"
 | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -31,37 +32,81 @@ func (m MapClaims) VerifyAudience(cmp string, req bool) bool { | ||||||
| 	return verifyAud(aud, cmp, req) | 	return verifyAud(aud, cmp, req) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // VerifyExpiresAt compares the exp claim against cmp.
 | // VerifyExpiresAt compares the exp claim against cmp (cmp <= exp).
 | ||||||
| // If required is false, this method will return true if the value matches or is unset
 | // If req is false, it will return true, if exp is unset.
 | ||||||
| func (m MapClaims) VerifyExpiresAt(cmp int64, req bool) bool { | func (m MapClaims) VerifyExpiresAt(cmp int64, req bool) bool { | ||||||
| 	exp, ok := m["exp"] | 	cmpTime := time.Unix(cmp, 0) | ||||||
|  | 
 | ||||||
|  | 	v, ok := m["exp"] | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return !req | 		return !req | ||||||
| 	} | 	} | ||||||
| 	switch expType := exp.(type) { | 
 | ||||||
|  | 	switch exp := v.(type) { | ||||||
| 	case float64: | 	case float64: | ||||||
| 		return verifyExp(int64(expType), cmp, req) | 		if exp == 0 { | ||||||
| 	case json.Number: | 			return verifyExp(nil, cmpTime, req) | ||||||
| 		v, _ := expType.Int64() |  | ||||||
| 		return verifyExp(v, cmp, req) |  | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		return verifyExp(&newNumericDateFromSeconds(exp).Time, cmpTime, req) | ||||||
|  | 	case json.Number: | ||||||
|  | 		v, _ := exp.Float64() | ||||||
|  | 
 | ||||||
|  | 		return verifyExp(&newNumericDateFromSeconds(v).Time, cmpTime, req) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return false | 	return false | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // VerifyIssuedAt compares the iat claim against cmp.
 | // VerifyIssuedAt compares the exp claim against cmp (cmp >= iat).
 | ||||||
| // If required is false, this method will return true if the value matches or is unset
 | // If req is false, it will return true, if iat is unset.
 | ||||||
| func (m MapClaims) VerifyIssuedAt(cmp int64, req bool) bool { | func (m MapClaims) VerifyIssuedAt(cmp int64, req bool) bool { | ||||||
| 	iat, ok := m["iat"] | 	cmpTime := time.Unix(cmp, 0) | ||||||
|  | 
 | ||||||
|  | 	v, ok := m["iat"] | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return !req | 		return !req | ||||||
| 	} | 	} | ||||||
| 	switch iatType := iat.(type) { | 
 | ||||||
|  | 	switch iat := v.(type) { | ||||||
| 	case float64: | 	case float64: | ||||||
| 		return verifyIat(int64(iatType), cmp, req) | 		if iat == 0 { | ||||||
| 	case json.Number: | 			return verifyIat(nil, cmpTime, req) | ||||||
| 		v, _ := iatType.Int64() |  | ||||||
| 		return verifyIat(v, cmp, req) |  | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		return verifyIat(&newNumericDateFromSeconds(iat).Time, cmpTime, req) | ||||||
|  | 	case json.Number: | ||||||
|  | 		v, _ := iat.Float64() | ||||||
|  | 
 | ||||||
|  | 		return verifyIat(&newNumericDateFromSeconds(v).Time, cmpTime, req) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // VerifyNotBefore compares the nbf claim against cmp (cmp >= nbf).
 | ||||||
|  | // If req is false, it will return true, if nbf is unset.
 | ||||||
|  | func (m MapClaims) VerifyNotBefore(cmp int64, req bool) bool { | ||||||
|  | 	cmpTime := time.Unix(cmp, 0) | ||||||
|  | 
 | ||||||
|  | 	v, ok := m["nbf"] | ||||||
|  | 	if !ok { | ||||||
|  | 		return !req | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	switch nbf := v.(type) { | ||||||
|  | 	case float64: | ||||||
|  | 		if nbf == 0 { | ||||||
|  | 			return verifyNbf(nil, cmpTime, req) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return verifyNbf(&newNumericDateFromSeconds(nbf).Time, cmpTime, req) | ||||||
|  | 	case json.Number: | ||||||
|  | 		v, _ := nbf.Float64() | ||||||
|  | 
 | ||||||
|  | 		return verifyNbf(&newNumericDateFromSeconds(v).Time, cmpTime, req) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return false | 	return false | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -72,24 +117,7 @@ func (m MapClaims) VerifyIssuer(cmp string, req bool) bool { | ||||||
| 	return verifyIss(iss, cmp, req) | 	return verifyIss(iss, cmp, req) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // VerifyNotBefore compares the nbf claim against cmp.
 | // Valid validates time based claims "exp, iat, nbf".
 | ||||||
| // If required is false, this method will return true if the value matches or is unset
 |  | ||||||
| func (m MapClaims) VerifyNotBefore(cmp int64, req bool) bool { |  | ||||||
| 	nbf, ok := m["nbf"] |  | ||||||
| 	if !ok { |  | ||||||
| 		return !req |  | ||||||
| 	} |  | ||||||
| 	switch nbfType := nbf.(type) { |  | ||||||
| 	case float64: |  | ||||||
| 		return verifyNbf(int64(nbfType), cmp, req) |  | ||||||
| 	case json.Number: |  | ||||||
| 		v, _ := nbfType.Int64() |  | ||||||
| 		return verifyNbf(v, cmp, req) |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Valid calidates time based claims "exp, iat, nbf".
 |  | ||||||
| // There is no accounting for clock skew.
 | // There is no accounting for clock skew.
 | ||||||
| // As well, if any of the above claims are not in the token, it will still
 | // As well, if any of the above claims are not in the token, it will still
 | ||||||
| // be considered a valid claim.
 | // be considered a valid claim.
 | ||||||
|  |  | ||||||
|  | @ -8,14 +8,36 @@ import ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type Parser struct { | type Parser struct { | ||||||
| 	ValidMethods         []string // If populated, only these methods will be considered valid
 | 	// If populated, only these methods will be considered valid.
 | ||||||
| 	UseJSONNumber        bool     // Use JSON Number format in JSON decoder
 | 	//
 | ||||||
| 	SkipClaimsValidation bool     // Skip claims validation during token parsing
 | 	// Deprecated: In future releases, this field will not be exported anymore and should be set with an option to NewParser instead.
 | ||||||
|  | 	ValidMethods []string | ||||||
|  | 
 | ||||||
|  | 	// Use JSON Number format in JSON decoder.
 | ||||||
|  | 	//
 | ||||||
|  | 	// Deprecated: In future releases, this field will not be exported anymore and should be set with an option to NewParser instead.
 | ||||||
|  | 	UseJSONNumber bool | ||||||
|  | 
 | ||||||
|  | 	// Skip claims validation during token parsing.
 | ||||||
|  | 	//
 | ||||||
|  | 	// Deprecated: In future releases, this field will not be exported anymore and should be set with an option to NewParser instead.
 | ||||||
|  | 	SkipClaimsValidation bool | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Parse parses, validates, and returns a token.
 | // NewParser creates a new Parser with the specified options
 | ||||||
|  | func NewParser(options ...ParserOption) *Parser { | ||||||
|  | 	p := &Parser{} | ||||||
|  | 
 | ||||||
|  | 	// loop through our parsing options and apply them
 | ||||||
|  | 	for _, option := range options { | ||||||
|  | 		option(p) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return p | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Parse parses, validates, verifies the signature and returns the parsed token.
 | ||||||
| // keyFunc will receive the parsed token and should return the key for validating.
 | // keyFunc will receive the parsed token and should return the key for validating.
 | ||||||
| // If everything is kosher, err will be nil
 |  | ||||||
| func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { | func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { | ||||||
| 	return p.ParseWithClaims(tokenString, MapClaims{}, keyFunc) | 	return p.ParseWithClaims(tokenString, MapClaims{}, keyFunc) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,29 @@ | ||||||
|  | package jwt | ||||||
|  | 
 | ||||||
|  | // ParserOption is used to implement functional-style options that modify the behaviour of the parser. To add
 | ||||||
|  | // new options, just create a function (ideally beginning with With or Without) that returns an anonymous function that
 | ||||||
|  | // takes a *Parser type as input and manipulates its configuration accordingly.
 | ||||||
|  | type ParserOption func(*Parser) | ||||||
|  | 
 | ||||||
|  | // WithValidMethods is an option to supply algorithm methods that the parser will check. Only those methods will be considered valid.
 | ||||||
|  | // It is heavily encouraged to use this option in order to prevent attacks such as https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/.
 | ||||||
|  | func WithValidMethods(methods []string) ParserOption { | ||||||
|  | 	return func(p *Parser) { | ||||||
|  | 		p.ValidMethods = methods | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithJSONNumber is an option to configure the underyling JSON parser with UseNumber
 | ||||||
|  | func WithJSONNumber() ParserOption { | ||||||
|  | 	return func(p *Parser) { | ||||||
|  | 		p.UseJSONNumber = true | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // WithoutClaimsValidation is an option to disable claims validation. This option should only be used if you exactly know
 | ||||||
|  | // what you are doing.
 | ||||||
|  | func WithoutClaimsValidation() ParserOption { | ||||||
|  | 	return func(p *Parser) { | ||||||
|  | 		p.SkipClaimsValidation = true | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -33,3 +33,14 @@ func GetSigningMethod(alg string) (method SigningMethod) { | ||||||
| 	} | 	} | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // GetAlgorithms returns a list of registered "alg" names
 | ||||||
|  | func GetAlgorithms() (algs []string) { | ||||||
|  | 	signingMethodLock.RLock() | ||||||
|  | 	defer signingMethodLock.RUnlock() | ||||||
|  | 
 | ||||||
|  | 	for alg := range signingMethods { | ||||||
|  | 		algs = append(algs, alg) | ||||||
|  | 	} | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -7,6 +7,14 @@ import ( | ||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | // DecodePaddingAllowed will switch the codec used for decoding JWTs respectively. Note that the JWS RFC7515
 | ||||||
|  | // states that the tokens will utilize a Base64url encoding with no padding. Unfortunately, some implementations
 | ||||||
|  | // of JWT are producing non-standard tokens, and thus require support for decoding. Note that this is a global
 | ||||||
|  | // variable, and updating it will change the behavior on a package level, and is also NOT go-routine safe.
 | ||||||
|  | // To use the non-recommended decoding, set this boolean to `true` prior to using this package.
 | ||||||
|  | var DecodePaddingAllowed bool | ||||||
|  | 
 | ||||||
| // TimeFunc provides the current time when parsing token to validate "exp" claim (expiration time).
 | // TimeFunc provides the current time when parsing token to validate "exp" claim (expiration time).
 | ||||||
| // You can override it to use another time value.  This is useful for testing or if your
 | // You can override it to use another time value.  This is useful for testing or if your
 | ||||||
| // server uses a different time zone than your tokens.
 | // server uses a different time zone than your tokens.
 | ||||||
|  | @ -29,11 +37,12 @@ type Token struct { | ||||||
| 	Valid     bool                   // Is the token valid?  Populated when you Parse/Verify a token
 | 	Valid     bool                   // Is the token valid?  Populated when you Parse/Verify a token
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // New creates a new Token.  Takes a signing method
 | // New creates a new Token with the specified signing method and an empty map of claims.
 | ||||||
| func New(method SigningMethod) *Token { | func New(method SigningMethod) *Token { | ||||||
| 	return NewWithClaims(method, MapClaims{}) | 	return NewWithClaims(method, MapClaims{}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // NewWithClaims creates a new Token with the specified signing method and claims.
 | ||||||
| func NewWithClaims(method SigningMethod, claims Claims) *Token { | func NewWithClaims(method SigningMethod, claims Claims) *Token { | ||||||
| 	return &Token{ | 	return &Token{ | ||||||
| 		Header: map[string]interface{}{ | 		Header: map[string]interface{}{ | ||||||
|  | @ -45,7 +54,8 @@ func NewWithClaims(method SigningMethod, claims Claims) *Token { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SignedString retrieves the complete, signed token
 | // SignedString creates and returns a complete, signed JWT.
 | ||||||
|  | // The token is signed using the SigningMethod specified in the token.
 | ||||||
| func (t *Token) SignedString(key interface{}) (string, error) { | func (t *Token) SignedString(key interface{}) (string, error) { | ||||||
| 	var sig, sstr string | 	var sig, sstr string | ||||||
| 	var err error | 	var err error | ||||||
|  | @ -82,15 +92,19 @@ func (t *Token) SigningString() (string, error) { | ||||||
| 	return strings.Join(parts, "."), nil | 	return strings.Join(parts, "."), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Parse parses, validates, and returns a token.
 | // Parse parses, validates, verifies the signature and returns the parsed token.
 | ||||||
| // keyFunc will receive the parsed token and should return the key for validating.
 | // keyFunc will receive the parsed token and should return the cryptographic key
 | ||||||
| // If everything is kosher, err will be nil
 | // for verifying the signature.
 | ||||||
| func Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { | // The caller is strongly encouraged to set the WithValidMethods option to
 | ||||||
| 	return new(Parser).Parse(tokenString, keyFunc) | // validate the 'alg' claim in the token matches the expected algorithm.
 | ||||||
|  | // For more details about the importance of validating the 'alg' claim,
 | ||||||
|  | // see https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/
 | ||||||
|  | func Parse(tokenString string, keyFunc Keyfunc, options ...ParserOption) (*Token, error) { | ||||||
|  | 	return NewParser(options...).Parse(tokenString, keyFunc) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) { | func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc, options ...ParserOption) (*Token, error) { | ||||||
| 	return new(Parser).ParseWithClaims(tokenString, claims, keyFunc) | 	return NewParser(options...).ParseWithClaims(tokenString, claims, keyFunc) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // EncodeSegment encodes a JWT specific base64url encoding with padding stripped
 | // EncodeSegment encodes a JWT specific base64url encoding with padding stripped
 | ||||||
|  | @ -106,5 +120,12 @@ func EncodeSegment(seg []byte) string { | ||||||
| // Deprecated: In a future release, we will demote this function to a non-exported function, since it
 | // Deprecated: In a future release, we will demote this function to a non-exported function, since it
 | ||||||
| // should only be used internally
 | // should only be used internally
 | ||||||
| func DecodeSegment(seg string) ([]byte, error) { | func DecodeSegment(seg string) ([]byte, error) { | ||||||
|  | 	if DecodePaddingAllowed { | ||||||
|  | 		if l := len(seg) % 4; l > 0 { | ||||||
|  | 			seg += strings.Repeat("=", 4-l) | ||||||
|  | 		} | ||||||
|  | 		return base64.URLEncoding.DecodeString(seg) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return base64.RawURLEncoding.DecodeString(seg) | 	return base64.RawURLEncoding.DecodeString(seg) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,127 @@ | ||||||
|  | package jwt | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"fmt" | ||||||
|  | 	"math" | ||||||
|  | 	"reflect" | ||||||
|  | 	"strconv" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // TimePrecision sets the precision of times and dates within this library.
 | ||||||
|  | // This has an influence on the precision of times when comparing expiry or
 | ||||||
|  | // other related time fields. Furthermore, it is also the precision of times
 | ||||||
|  | // when serializing.
 | ||||||
|  | //
 | ||||||
|  | // For backwards compatibility the default precision is set to seconds, so that
 | ||||||
|  | // no fractional timestamps are generated.
 | ||||||
|  | var TimePrecision = time.Second | ||||||
|  | 
 | ||||||
|  | // MarshalSingleStringAsArray modifies the behaviour of the ClaimStrings type, especially
 | ||||||
|  | // its MarshalJSON function.
 | ||||||
|  | //
 | ||||||
|  | // If it is set to true (the default), it will always serialize the type as an
 | ||||||
|  | // array of strings, even if it just contains one element, defaulting to the behaviour
 | ||||||
|  | // of the underlying []string. If it is set to false, it will serialize to a single
 | ||||||
|  | // string, if it contains one element. Otherwise, it will serialize to an array of strings.
 | ||||||
|  | var MarshalSingleStringAsArray = true | ||||||
|  | 
 | ||||||
|  | // NumericDate represents a JSON numeric date value, as referenced at
 | ||||||
|  | // https://datatracker.ietf.org/doc/html/rfc7519#section-2.
 | ||||||
|  | type NumericDate struct { | ||||||
|  | 	time.Time | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewNumericDate constructs a new *NumericDate from a standard library time.Time struct.
 | ||||||
|  | // It will truncate the timestamp according to the precision specified in TimePrecision.
 | ||||||
|  | func NewNumericDate(t time.Time) *NumericDate { | ||||||
|  | 	return &NumericDate{t.Truncate(TimePrecision)} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // newNumericDateFromSeconds creates a new *NumericDate out of a float64 representing a
 | ||||||
|  | // UNIX epoch with the float fraction representing non-integer seconds.
 | ||||||
|  | func newNumericDateFromSeconds(f float64) *NumericDate { | ||||||
|  | 	round, frac := math.Modf(f) | ||||||
|  | 	return NewNumericDate(time.Unix(int64(round), int64(frac*1e9))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // MarshalJSON is an implementation of the json.RawMessage interface and serializes the UNIX epoch
 | ||||||
|  | // represented in NumericDate to a byte array, using the precision specified in TimePrecision.
 | ||||||
|  | func (date NumericDate) MarshalJSON() (b []byte, err error) { | ||||||
|  | 	f := float64(date.Truncate(TimePrecision).UnixNano()) / float64(time.Second) | ||||||
|  | 
 | ||||||
|  | 	return []byte(strconv.FormatFloat(f, 'f', -1, 64)), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UnmarshalJSON is an implementation of the json.RawMessage interface and deserializses a
 | ||||||
|  | // NumericDate from a JSON representation, i.e. a json.Number. This number represents an UNIX epoch
 | ||||||
|  | // with either integer or non-integer seconds.
 | ||||||
|  | func (date *NumericDate) UnmarshalJSON(b []byte) (err error) { | ||||||
|  | 	var ( | ||||||
|  | 		number json.Number | ||||||
|  | 		f      float64 | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	if err = json.Unmarshal(b, &number); err != nil { | ||||||
|  | 		return fmt.Errorf("could not parse NumericData: %w", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if f, err = number.Float64(); err != nil { | ||||||
|  | 		return fmt.Errorf("could not convert json number value to float: %w", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	n := newNumericDateFromSeconds(f) | ||||||
|  | 	*date = *n | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ClaimStrings is basically just a slice of strings, but it can be either serialized from a string array or just a string.
 | ||||||
|  | // This type is necessary, since the "aud" claim can either be a single string or an array.
 | ||||||
|  | type ClaimStrings []string | ||||||
|  | 
 | ||||||
|  | func (s *ClaimStrings) UnmarshalJSON(data []byte) (err error) { | ||||||
|  | 	var value interface{} | ||||||
|  | 
 | ||||||
|  | 	if err = json.Unmarshal(data, &value); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var aud []string | ||||||
|  | 
 | ||||||
|  | 	switch v := value.(type) { | ||||||
|  | 	case string: | ||||||
|  | 		aud = append(aud, v) | ||||||
|  | 	case []string: | ||||||
|  | 		aud = ClaimStrings(v) | ||||||
|  | 	case []interface{}: | ||||||
|  | 		for _, vv := range v { | ||||||
|  | 			vs, ok := vv.(string) | ||||||
|  | 			if !ok { | ||||||
|  | 				return &json.UnsupportedTypeError{Type: reflect.TypeOf(vv)} | ||||||
|  | 			} | ||||||
|  | 			aud = append(aud, vs) | ||||||
|  | 		} | ||||||
|  | 	case nil: | ||||||
|  | 		return nil | ||||||
|  | 	default: | ||||||
|  | 		return &json.UnsupportedTypeError{Type: reflect.TypeOf(v)} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	*s = aud | ||||||
|  | 
 | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (s ClaimStrings) MarshalJSON() (b []byte, err error) { | ||||||
|  | 	// This handles a special case in the JWT RFC. If the string array, e.g. used by the "aud" field,
 | ||||||
|  | 	// only contains one element, it MAY be serialized as a single string. This may or may not be
 | ||||||
|  | 	// desired based on the ecosystem of other JWT library used, so we make it configurable by the
 | ||||||
|  | 	// variable MarshalSingleStringAsArray.
 | ||||||
|  | 	if len(s) == 1 && !MarshalSingleStringAsArray { | ||||||
|  | 		return json.Marshal(s[0]) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return json.Marshal([]string(s)) | ||||||
|  | } | ||||||
|  | @ -4,7 +4,7 @@ | ||||||
| 
 | 
 | ||||||
| // Package acme provides an implementation of the
 | // Package acme provides an implementation of the
 | ||||||
| // Automatic Certificate Management Environment (ACME) spec.
 | // Automatic Certificate Management Environment (ACME) spec.
 | ||||||
| // The intial implementation was based on ACME draft-02 and
 | // The initial implementation was based on ACME draft-02 and
 | ||||||
| // is now being extended to comply with RFC 8555.
 | // is now being extended to comply with RFC 8555.
 | ||||||
| // See https://tools.ietf.org/html/draft-ietf-acme-acme-02
 | // See https://tools.ietf.org/html/draft-ietf-acme-acme-02
 | ||||||
| // and https://tools.ietf.org/html/rfc8555 for details.
 | // and https://tools.ietf.org/html/rfc8555 for details.
 | ||||||
|  |  | ||||||
|  | @ -410,3 +410,29 @@ func isAlreadyRevoked(err error) bool { | ||||||
| 	e, ok := err.(*Error) | 	e, ok := err.(*Error) | ||||||
| 	return ok && e.ProblemType == "urn:ietf:params:acme:error:alreadyRevoked" | 	return ok && e.ProblemType == "urn:ietf:params:acme:error:alreadyRevoked" | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // ListCertAlternates retrieves any alternate certificate chain URLs for the
 | ||||||
|  | // given certificate chain URL. These alternate URLs can be passed to FetchCert
 | ||||||
|  | // in order to retrieve the alternate certificate chains.
 | ||||||
|  | //
 | ||||||
|  | // If there are no alternate issuer certificate chains, a nil slice will be
 | ||||||
|  | // returned.
 | ||||||
|  | func (c *Client) ListCertAlternates(ctx context.Context, url string) ([]string, error) { | ||||||
|  | 	if _, err := c.Discover(ctx); err != nil { // required by c.accountKID
 | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	defer res.Body.Close() | ||||||
|  | 
 | ||||||
|  | 	// We don't need the body but we need to discard it so we don't end up
 | ||||||
|  | 	// preventing keep-alive
 | ||||||
|  | 	if _, err := io.Copy(ioutil.Discard, res.Body); err != nil { | ||||||
|  | 		return nil, fmt.Errorf("acme: cert alternates response stream: %v", err) | ||||||
|  | 	} | ||||||
|  | 	alts := linkHeader(res.Header, "alternate") | ||||||
|  | 	return alts, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -6,12 +6,11 @@ github.com/Azure/azure-sdk-for-go/storage | ||||||
| github.com/Azure/azure-sdk-for-go/version | github.com/Azure/azure-sdk-for-go/version | ||||||
| # github.com/Azure/go-autorest v14.2.0+incompatible | # github.com/Azure/go-autorest v14.2.0+incompatible | ||||||
| github.com/Azure/go-autorest | github.com/Azure/go-autorest | ||||||
| # github.com/Azure/go-autorest/autorest v0.11.20 | # github.com/Azure/go-autorest/autorest v0.11.24 | ||||||
| ## explicit | ## explicit | ||||||
| github.com/Azure/go-autorest/autorest | github.com/Azure/go-autorest/autorest | ||||||
| github.com/Azure/go-autorest/autorest/azure | github.com/Azure/go-autorest/autorest/azure | ||||||
| # github.com/Azure/go-autorest/autorest/adal v0.9.15 | # github.com/Azure/go-autorest/autorest/adal v0.9.18 | ||||||
| ## explicit |  | ||||||
| github.com/Azure/go-autorest/autorest/adal | github.com/Azure/go-autorest/autorest/adal | ||||||
| # github.com/Azure/go-autorest/autorest/date v0.3.0 | # github.com/Azure/go-autorest/autorest/date v0.3.0 | ||||||
| github.com/Azure/go-autorest/autorest/date | github.com/Azure/go-autorest/autorest/date | ||||||
|  | @ -115,7 +114,7 @@ github.com/felixge/httpsnoop | ||||||
| # github.com/gofrs/uuid v4.0.0+incompatible | # github.com/gofrs/uuid v4.0.0+incompatible | ||||||
| ## explicit | ## explicit | ||||||
| github.com/gofrs/uuid | github.com/gofrs/uuid | ||||||
| # github.com/golang-jwt/jwt/v4 v4.0.0 | # github.com/golang-jwt/jwt/v4 v4.2.0 | ||||||
| github.com/golang-jwt/jwt/v4 | github.com/golang-jwt/jwt/v4 | ||||||
| # github.com/golang/protobuf v1.3.2 | # github.com/golang/protobuf v1.3.2 | ||||||
| github.com/golang/protobuf/proto | github.com/golang/protobuf/proto | ||||||
|  | @ -184,7 +183,7 @@ github.com/yvasiyarov/gorelic | ||||||
| # github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f | # github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f | ||||||
| ## explicit | ## explicit | ||||||
| github.com/yvasiyarov/newrelic_platform_go | github.com/yvasiyarov/newrelic_platform_go | ||||||
| # golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 | # golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 | ||||||
| ## explicit | ## explicit | ||||||
| golang.org/x/crypto/acme | golang.org/x/crypto/acme | ||||||
| golang.org/x/crypto/acme/autocert | golang.org/x/crypto/acme/autocert | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue