Spring-boot: Rename jwt.jwk.set-uri to jwt.jwk-set-uri and relocate to spring.security.oauth2.resourceserver

Created on 21 Aug 2018  路  14Comments  路  Source: spring-projects/spring-boot

The property for configuring a jwk set uri on an OAuth 2.0 Resource Server is

spring.security.oauth2.resource.jwt.jwk.set-uri

Which is sensible in that it is close to the property hierarchy from legacy oauth. (This differs only in the leaf, which in legacy oauth is called key-set-uri.)

It would be clearer to the user what they are configuring with the following property name:

spring.security.oauth2.resource-server.jwt.jwk-set-uri

There are a few reasons for this.

First, resource server is consistently referred to as such throughout the Spring Security codebase, so a departure from that feels inconsistent.

And while it may feel familiar to those who are used to the legacy oauth property set, "resource-server" is clearer as "resource" carries other semantic meanings including the much more prevalent one used throughout Spring, referring to some kind of external asset like a File or a Database.

Finally, there is value in the symmetry between the DSL:

http.
    oauth2().
        resourceServer()
            .jwt()

And the property name:

```yaml:
spring.security:
oauth2:
resource-server:
jwt:

As for `jwk.set-uri` vs `jwk-set-uri`, the latter is more semantically clear because there isn't a notion of a "set-uri" in the specification, but there is a notion of a "[JWK Set](https://tools.ietf.org/html/rfc7517#section-2)":

> JWK Set
      A JSON object that represents a set of JWKs.  The JSON object MUST
      have a "keys" member, which is an array of JWKs.

And while it is arguable that a JWK Set could possibly be configured in ways other than by uri, making `jwk-set.uri` a possibility, it probably isn't a good fit for boot to support our other use cases. For example, it's reasonable to suppose that a user might want to supply the JWK Set by hand (hardcoded). However, this doesn't allow the user to configure key rotation, making it an edge case for those who need it just for testing or the like.

Also, while less important, there is a nice symmetry between the existing DSL:

```java
http.
    oauth2().
        resourceServer()
            .jwt()
                .jwkSetUri("https://issuer/jwk-set-uri");

And the proposed property name:

spring.security:
  oauth2:
    resource-server:
      jwt:
        jwk-set-uri: https://issuer/jwk-set-uri
task

Most helpful comment

Agreed @vpavic, that's why I edited my comment to remove that part of my comment and prevent more comments. Too late I can see :) - For the record I only mentioned server as a way to gather those props. Again, I never implied server.resource. I think we're sold on resourceserver now.

All 14 comments

I think I'm fine with resource being renamed to resource-server. We had a discussion on slack on whether we wanted the set-uri under a jwk namespace or if the property should be jwk-set-uri. The argument for adding a separate namespace was it makes adding properties in the future easier. If there was any other configuration for JWK, it would be added under that namespace.

I am not fine with resource being renamed to resource-server as we don't used dashed words for groups. And +1 with the separate namespace.

I am not fine with resource being renamed to resource-server as we don't used dashed words for groups.

While considering this, please take into account what will happen when Authorization Server support comes into the play.

If you're sticking with resource, that would suggest authorization consistency wise and that doesn't sound nice. IMO in cases like this a level of connection with the domain in subject should be kept. Perhaps both resource and authorization could be grouped together under server? That would also fit nicely along with client.

If there was any other configuration for JWK, it would be added under that namespace.

From the perspective of the domain in subject, as @jzheaux suggests, this is about _JWK Set_ and not _JWK_ and it doesn't really make sense to express set-uri as a property of jwk. Related metadata specs (see [1] and [2]) describe this as jwks_uri, and there's also no other mention of JWK.

[1] http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
[2] https://tools.ietf.org/html/rfc8414#section-2

If you're sticking with resource

Thanks for the feedback but I never meant to say that I don't want this group to be renamed. I merely mentioned we don't use several words for groups.

We had a discussion on slack on whether we wanted the set-uri under a jwk namespace or if the property should be jwk-set-uri.

Yes, you are right, @mbhave, I should have mentioned that in the ticket. We decided to raise this ticket after some further internal review of the property name.

The argument for adding a separate namespace was it makes adding properties in the future easier. If there was any other configuration for JWK, it would be added under that namespace.

The concern is that it isn't JWK that we are configuring, but instead we are configuring how JWTs should be verified, and a term that is used consistently to talk about verifying JWTs with a JWK is "JWK Set Uri" (as @vpavic noted, jwks_url is also used in one of the specs). Hypothetically, if we introduced JWK as a first-class configurable concept, then spring.security.oauth2.resource.jwk would probably be more appropriate since JWK as a spec isn't intrinsically bound to JWT.

For example, while it would be semantically weaker, we could call the property spring.security.oauth2.resource.jwt.keys-uri and it would still be correct. The downside here is that we have lost the clarity that the user is configuring jwt to use a jwk set for its set of keys.

I am not fine with resource being renamed to resource-server as we don't used dashed words for groups.

@snicoll, just for my curiosity, could you explain your team's reasoning on this? I'm not in opposition, but knowing the rationale will help me think of other possibilities.

Just a quick survey shows some multi-word groups, but that aren't hyphenated, and I wonder what is your opinion on that:

spring.mvc.contentnegotiation.favor-parameter
spring.mvc.formcontent.putfilter.enabled
server.tomcat.accesslog.buffered

Are you okay with multi-word groups so long as they are not hyphenated?

Are you okay with multi-word groups so long as they are not hyphenated?

It's not about me btw and yes, that's what I meant. The reasoning is that the prefix (group) should be structured with single "words" separated with dots and only the property has the kebab case format to separate it properly from the rest.

We've discussed this issue based on the feedback so far one at the team call and have a proposition that @mbhave intend to summarize shortly. Thanks!

@vpavic @jzheaux thanks for the explanation. I do see your point about "JWK Set Uri" being used to configure how JWTs are validated. I agree that a jwk-set-uri property makes more sense in that case.

For the resource-server change, we discussed this on our team call and we've decided to go with what @vpavic suggested about grouping both authorization and resource server under the server namespace.

After discussing with @rwinch and @jzheaux, having a top level server namespace doesn't seem to make much sense. The OAuth concept is Resource Server and Authorization server. Configuring server.authorization seems to imply that we're configuring the authorization for a server rather than the Authorization Server itself.

@snicoll Correct me if I'm wrong but we don't use - in group names because it could mess with binding? #11090 might have some details. In that case, resourceserver seems to be the best option.

That and we want the structure of the group to be different from the structure of the property. We use dots as a way to find the parts of a prefix and this can be a problem with env variables.

- in group names because it could mess with binding... That and we want the structure of the group to be different from the structure of the property

@snicoll, Just for my own understanding, can you explain why you want the structure of the group to be different from the structure of the property? Sounds like part of it might be tech limitations, are there other reasons?

I still think that a server parent makes sense

What is the advantage of keeping it server.resource and server.authorization?

The first, "server resource" reads like it is referring to a resource _on a_ server. This is the semantically closer reading when the words are in that order. Certainly a "Server Resource" is much different from a "Resource Server".

The second, "server authorization" reads like it is referring to the authorization aspects _of a_ server as opposed to the configuration of an "Authorization Server".

Much like "JWK Set Uri" is the term that is used to refer to its concept, "Resource Server" is the term used to refer to OAuth Resource Servers. If we look at the full grouping spring.security.oauth2.server.resource, this reads much more like "OAuth2 Server" is a concept and an "OAuth2 Server Resource" is what is being configured, which isn't the case.

Like this property in boot:

server.tomcat.accesslog.file-date-format

It would be confusing to do:

server.tomcat.log.access.file-date-format

Because that would imply that we are talking about access _to_ logs. Because "log" and "access" can both modify one another, the order matters. It is also true that "accesslog" is the term that folks are familiar with and would readily understand.

Likewise, "resourceserver" is the term that engineers understand and see when they go through reading materials and in their discussions with one another.

And doing spring.security.oauth2.[client|authorizationserver|resourceserver] also has the value that all three OAuth2 notions are at the same level hierarchically. This is important because each is a first-class entity in OAuth2.

That is, OAuth2 isn't just a client and a server, but a client and two servers, so it is valuable differentiate regarding which server is being configured. Thus the concepts "OAuth2 Client", "OAuth2 Resource Server", and "OAuth2 Authorization Server" are the common terminology.

I have seen libraries that use the term "OAuth2 Server" to (ambiguously) refer to an "Authorization Server". This is an additional reason to not do spring.security.oauth2.server.resource as folks may surmise quite reasonably that the property is referring to "OAuth2 Authorization Server" configuration.

I still think that a server parent makes sense.

Assuming - is out of the question, looking at the broader picture I agree that spring.security.oauth2.resourceserver still reads better (than spring.security.oauth2.server.resource), and is more consistent with both _Spring Security OAuth2 Resource Server_ and the configuration DSL itself.

Also with stuff like contentnegotiation already in place, resourceserver and authorizationserver should probably be acceptable as well.

Agreed @vpavic, that's why I edited my comment to remove that part of my comment and prevent more comments. Too late I can see :) - For the record I only mentioned server as a way to gather those props. Again, I never implied server.resource. I think we're sold on resourceserver now.

@snicoll

Using resourceserver and later authorizationserver sounds good to me.

For my (our) own education, can you elaborate on

1) What problems having - in a group structure would cause?
2) Why "we want the structure of the group to be different from the structure of the property"

@rwinch

What problems having - in a group structure would cause?

Using dashes in the prefix is problematic because they do not follow the same binding rules as the names. It basically causes a ton of confusion so we try not to use them. For example, given a @ConfigurationProperties("foo.bar") and a field firstName, you can bind using any of the following:

foo.bar.first-name // canonical
foo.bar.firstName // java style
FOO_BAR_FIRSTNAME // environment variable

If the prefix were foo-bar the "java style" and "environment variable style" start to look very odd.

Was this page helpful?
0 / 5 - 0 ratings