Skip to content

Commit

Permalink
Use inlined jwks when set in JWT policy (istio#16642)
Browse files Browse the repository at this point in the history
  • Loading branch information
yangminzhu authored and istio-testing committed Aug 30, 2019
1 parent c4db9cb commit a6e26c7
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 8 deletions.
4 changes: 2 additions & 2 deletions pilot/pkg/model/jwks_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ func (r *JwksResolver) SetAuthenticationPolicyJwksURIs(policy *authn.Policy) err
switch method.GetParams().(type) {
case *authn.PeerAuthenticationMethod_Jwt:
policyJwt := method.GetJwt()
if policyJwt.JwksUri == "" {
if policyJwt.JwksUri == "" && policyJwt.Jwks == "" {
uri, err := r.resolveJwksURIUsingOpenID(policyJwt.Issuer)
if err != nil {
log.Warnf("Failed to get jwks_uri for issuer %q: %v", policyJwt.Issuer, err)
Expand All @@ -196,7 +196,7 @@ func (r *JwksResolver) SetAuthenticationPolicyJwksURIs(policy *authn.Policy) err
for _, method := range policy.Origins {
// JWT is only allowed authentication method type for Origin.
policyJwt := method.GetJwt()
if policyJwt.JwksUri == "" {
if policyJwt.JwksUri == "" && policyJwt.Jwks == "" {
uri, err := r.resolveJwksURIUsingOpenID(policyJwt.Issuer)
if err != nil {
log.Warnf("Failed to get jwks_uri for issuer %q: %v", policyJwt.Issuer, err)
Expand Down
25 changes: 25 additions & 0 deletions pilot/pkg/model/jwks_resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,27 @@ func TestSetAuthenticationPolicyJwksURIs(t *testing.T) {
},
PrincipalBinding: authn.PrincipalBinding_USE_ORIGIN,
},
"jwks": {
Targets: []*authn.TargetSelector{{
Name: "two",
Ports: []*authn.PortSelector{
{
Port: &authn.PortSelector_Number{
Number: 80,
},
},
},
}},
Origins: []*authn.OriginAuthenticationMethod{
{
Jwt: &authn.Jwt{
Issuer: "http://abc",
Jwks: "JSONWebKeySet",
},
},
},
PrincipalBinding: authn.PrincipalBinding_USE_ORIGIN,
},
}

cases := []struct {
Expand All @@ -138,6 +159,10 @@ func TestSetAuthenticationPolicyJwksURIs(t *testing.T) {
in: authNPolicies["two"],
expected: "http://xyz",
},
{
in: authNPolicies["jwks"],
expected: "",
},
}
for _, c := range cases {
_ = r.SetAuthenticationPolicyJwksURIs(c.in)
Expand Down
20 changes: 14 additions & 6 deletions pilot/pkg/security/authn/v1alpha1/policy_applier.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,13 @@ func convertToEnvoyJwtConfig(policyJwts []*authn_v1alpha1.Jwt) *envoy_jwt.JwtAut
}
provider.FromParams = policyJwt.JwtParams

jwtPubKey, err := authn_model.JwtKeyResolver.GetPublicKey(policyJwt.JwksUri)
if err != nil {
log.Errorf("Failed to fetch jwt public key from %q: %s", policyJwt.JwksUri, err)
jwtPubKey := policyJwt.Jwks
if jwtPubKey == "" {
var err error
jwtPubKey, err = authn_model.JwtKeyResolver.GetPublicKey(policyJwt.JwksUri)
if err != nil {
log.Errorf("Failed to fetch jwt public key from %q: %s", policyJwt.JwksUri, err)
}
}
provider.JwksSourceSpecifier = &envoy_jwt.JwtProvider_LocalJwks{
LocalJwks: &core.DataSource{
Expand Down Expand Up @@ -191,9 +195,13 @@ func convertToIstioJwtConfig(policyJwts []*authn_v1alpha1.Jwt) *istio_jwt.JwtAut
}
jwt.FromParams = policyJwt.JwtParams

jwtPubKey, err := authn_model.JwtKeyResolver.GetPublicKey(policyJwt.JwksUri)
if err != nil {
log.Errorf("Failed to fetch jwt public key from %q: %s", policyJwt.JwksUri, err)
jwtPubKey := policyJwt.Jwks
if jwtPubKey == "" {
var err error
jwtPubKey, err = authn_model.JwtKeyResolver.GetPublicKey(policyJwt.JwksUri)
if err != nil {
log.Errorf("Failed to fetch jwt public key from %q: %s", policyJwt.JwksUri, err)
}
}

// Put empty string in config even if above ResolveJwtPubKey fails.
Expand Down
74 changes: 74 additions & 0 deletions pilot/pkg/security/authn/v1alpha1/policy_applier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,37 @@ func TestConvertPolicyToJwtConfig(t *testing.T) {
AllowMissingOrFailed: true,
},
},
{
in: &authn.Policy{
Peers: []*authn.PeerAuthenticationMethod{
{
Params: &authn.PeerAuthenticationMethod_Jwt{
Jwt: &authn.Jwt{
Jwks: test.JwtPubKey1,
},
},
},
},
},
wantName: "jwt-auth",
useIstioJWT: true,
wantConfig: &istio_jwt.JwtAuthentication{
Rules: []*istio_jwt.JwtRule{
{
JwksSourceSpecifier: &istio_jwt.JwtRule_LocalJwks{
LocalJwks: &istio_jwt.DataSource{
Specifier: &istio_jwt.DataSource_InlineString{
InlineString: test.JwtPubKey1,
},
},
},
Forward: true,
ForwardPayloadHeader: "istio-sec-da39a3ee5e6b4b0d3255bfef95601890afd80709",
},
},
AllowMissingOrFailed: true,
},
},
{
in: &authn.Policy{
Origins: []*authn.OriginAuthenticationMethod{
Expand Down Expand Up @@ -319,6 +350,49 @@ func TestConvertPolicyToJwtConfig(t *testing.T) {
},
},
},
{
in: &authn.Policy{
Origins: []*authn.OriginAuthenticationMethod{
{
Jwt: &authn.Jwt{
Issuer: "issuer-1",
Jwks: test.JwtPubKey2,
},
},
},
},
wantName: "envoy.filters.http.jwt_authn",
wantConfig: &envoy_jwt.JwtAuthentication{
Rules: []*envoy_jwt.RequirementRule{
{
Match: &route.RouteMatch{
PathSpecifier: &route.RouteMatch_Prefix{
Prefix: "/",
},
},
Requires: &envoy_jwt.JwtRequirement{
RequiresType: &envoy_jwt.JwtRequirement_AllowMissingOrFailed{
AllowMissingOrFailed: &types.Empty{},
},
},
},
},
Providers: map[string]*envoy_jwt.JwtProvider{
"origins-0": {
Issuer: "issuer-1",
JwksSourceSpecifier: &envoy_jwt.JwtProvider_LocalJwks{
LocalJwks: &core.DataSource{
Specifier: &core.DataSource_InlineString{
InlineString: test.JwtPubKey2,
},
},
},
Forward: true,
PayloadInMetadata: "issuer-1",
},
},
},
},
}

for _, c := range cases {
Expand Down

0 comments on commit a6e26c7

Please sign in to comment.