Skip to content

Add Token Endpoint #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jzheaux opened this issue Apr 3, 2020 · 35 comments
Closed

Add Token Endpoint #3

jzheaux opened this issue Apr 3, 2020 · 35 comments
Assignees
Labels
status: duplicate A duplicate of another issue

Comments

@jzheaux
Copy link
Contributor

jzheaux commented Apr 3, 2020

An authorization server should support a /token endpoint.

On this first iteration, the endpoint should support the client credentials grant gh-5. Namely, it should verify the grant_type parameter, and formulate a JWT based on the authenticated client.

Like the JWK Set Endpoint gh-2, this should be a Servlet Filter. It will likely sit later on in the Spring Security filter chain, post-authentication. As such, it can read the current authentication from the SecurityContextHolder.

The Nimbus library should be used for generating the JWT.

The JWT should contain jti, iss, sub, exp, and iat claims. Support for scp, aud, and nbf can be added later on.

The jti claim should be a GUID. The sub claim in the JWT should be the result of Authentication#getName. The exp claim should be a reasonable time in the future, and the iat claim should be the current time when the JWT is formulated. The iss claim could be hard-coded for now.

@rwinch rwinch added this to the 0.0.1 milestone Apr 9, 2020
@protyay
Copy link

protyay commented Apr 16, 2020

Hello @rwinch , Is this something I can work on ? I do have professional working experience with Spring projects.
Thanks.

@jgrandja
Copy link
Collaborator

Thanks for the offer @protyay. Please go ahead and let us know if you have any questions.

@jgrandja jgrandja added the type: enhancement A general enhancement label Apr 16, 2020
@dfcoffin
Copy link

@rwinch Is there a reason the client credentials grant is only supporting a JWT base and not a JWT and opaque Bearer Token? RFC 6750 was issued prior to any of the JWT standards.

@tomvandenberge
Copy link

That's an interesting question. I agree that the standard allows using opaque tokens. But I don't know if that's used often. If I'm not mistaken, the current implementation in spring-security-oauth only supports JWT access tokens (not entirely sure though). Maybe it's a good idea to make this pluggable somehow.

@jzheaux
Copy link
Contributor Author

jzheaux commented Apr 16, 2020

@dfcoffin I think for the first release the proposal is to support the JWT format and the client credentials grant. That's not to say that in future releases other support won't be added.

@ziodave
Copy link

ziodave commented Apr 16, 2020

Both Spring Security 5.2 and Spring Security OAuth 2.3 support Opaque Tokens, examples linked from the Migration Guide. As a reference see also the Features’ Matrix.

@jgrandja
Copy link
Collaborator

@dfcoffin Just to clear things up, #19 is what we are targeting for the initial set of work. There is so much more work to be done as you can imagine. And this includes logging all the issues and grouping them in epics. We are starting with the simple flow client_credentials that has the least moving parts. We will gradually move towards the more complicated parts such as authorization_code.

@dfcoffin
Copy link

@jzheaux If the intent is to provide Authorization Server support for OpenID connect in the same manner Spring Security was upgraded, then test JWT needs to be first. However, I am responsible for assisting Utilities in the implementation of the Green Button standards (a.k.a North American Energy Standards Board (NAESB) Retail Energy Quadrant book 21 (REQ.21) Energy Service Provider Interface (ESPI)), which only provides support for an opaque token. It was developed by Pivotal for NIST in support of the standard and prior to the existence of any JWT RFCs.

If the initial implementation only supports JWT format for the client credentials grant, it will be a long time before I will be able to recommend the deployment of a Spring Authorization Server. Instead, I will be forced to continue to recommend the now deprecated spring-security-oauth project, which will be supported until March 2021.

@dfcoffin
Copy link

@jgrandja It would be nice if after the project is better defined an implementation milestone map, similar to the one done for the Spring Security OAuth upgrade, is made available.

@jgrandja
Copy link
Collaborator

@dfcoffin For sure, a roadmap for the set of features is necessary so users can see the high level view of what will be delivered and have their vote on it so we can prioritize. When the initial roadmap is planned out it will be published so all can view and track against it.

As per your comment, both JWT and opaque token would need to be supported before we release 1.0.0.

@protyay
Copy link

protyay commented Apr 17, 2020

@jgrandja @jzheaux
Thank you.
Just to reiterate, this is the implementation of Section 1.3.4 Client Credentials of RFC 6479

Please verify the following comments for a better understanding.

  1. The grant_type parameter is the Client Credentials with params Client Secret & Client ID?

  2. The /token endpoint accepts the above params, and on verification, returns a JWT.

  3. I'm afraid that I don't see the responsibility of the filter when we have the above endpoint.

this should be a Servlet Filter. It will likely sit later on in the Spring Security filter chain, post-authentication

@dfcoffin
Copy link

@protyay I think Section 3.2 Token Endpoint of RFC 6749 has a better definition of the /token endpoint general requirements

@anoopgarlapati
Copy link
Contributor

@protyay For 3, I believe what @jzheaux meant is the /token endpoint is implemented as a Filter rather than a Spring MVC endpoint similar to how /login endpoint is implemented as a filter here. This filter will later be configured to sit after authentication filters and since it will be after the authentication filters, this filter can read authentication from SecurityContextHolder wherever needed.

@tomvandenberge
Copy link

tomvandenberge commented Apr 18, 2020

I have to say I'm sharing @protyay's confusion about implementing the token endpoint as a filter.

Filters are invoked before the request ends up at a servlet. I don't see how (or why) you would implement an endpoint in a filter instead of a servlet.

@protyay
Copy link

protyay commented Apr 18, 2020

@dfcoffin Thanks . I've read the RFC relevant sections to better understand the contract of the /token endpoint. I don't specifically understand, what @tomvandenberge mentions in the above comment, how I should implement it as a Filter

@anoopgarlapati I would like to believe that the link that you have provided is what the implementation should look like. Although if you would visit the RFC 6479 standard documentation, it clearly says of an API implementation.

@paurav-munshi
Copy link
Contributor

@protyay @tomvandenberge

how I should implement it as a Filter

Technically speaking it is possible to do that in filter. You can post your response to output stream from filter and close it and also not call chain.doFilter. This will eventually not call the servlet and also commit the response, effectively acting as an endpoint.

I don't see how (or why) you would implement an endpoint in a filter instead of a servlet.

Though I am also not sure why we want to do it like that. I would assume that using filter can be easily plugged in an existing spring security application (I am still new to spring security).

My suggestion would be that the client credentials authentication can be done as a filter and the actual token generation can be done in a controller(or servlet) and then later on for each type of grant type we can add filters.

Hope it makes sense.

@dfcoffin
Copy link

@protyay @tomvandenberge @paurav-munshi

I too am confused about how a /token endpoint filter will work, since filters are performed priorbe to any API controller. Section 4.4.3. Access Token Response contains the following sample response:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
  "access_token":"2YotnFZFEjr1zCsicMWpAA",
  "token_type":"example",
  "expires_in":3600,
  "example_parameter":"example_value"
}

The last value "example_parameter" is intended to allow the implementer to provide customized response elements. If the /token endpoint is implemented as a filter, this will require the ability for an implementation to access a "TokenEnhancer" class after creating the token but before sending a response. This doesn't seem like logic that should be in a filter.

The filter should only validate that the client_credential request is validly formed and the Basic Authorization in the HTTP Authorization Header is valid as required by Section 4.4.2. Access Token Request.

@protyay
Copy link

protyay commented Apr 18, 2020

@paurav-munshi
Even if it's technically possible, it violates what the RFC 6479 outlines as the standard implementation approach.
That's where the confusion lies

@eicki
Copy link

eicki commented Apr 18, 2020

I think the main question is do we consider this project a standalone authorization server only or a library that you can include in your app based on spring security to make it an authorization server. Spring Security is all about defining filters, so I think it is easier if everything is a filter in the latter use case.

@protyay
Copy link

protyay commented Apr 18, 2020

@eicki

This is from the README for this Project. I think we can safely assume we are not building a library here.

The ultimate goal of this project is to replace the Authorization Server support provided by Spring Security OAuth.

@dfcoffin
Copy link

dfcoffin commented Apr 18, 2020

@protyay @paurav-munshi

I think I can clarify some of the confusion.

Issue #5 implements the client_credentials filter which performs authentication of the Basic Authentication header as required Section 4.4.2. Access Token Request

Issue #3 implements the /token API endpoint which implements Section 4.4.3 Access Token Response

The question I have is which of these issues generates the jwt token?

@eicki
Copy link

eicki commented Apr 18, 2020

Actually that is what I use, we have a Spring Security Based App and use Spring Security OAuth to enable our app to act as authorization server as well

@eicki

This is from the README for this Project. I think we can safely assume we are not building a library here.

The ultimate goal of this project is to replace the Authorization Server support provided by Spring Security OAuth.

@paurav-munshi
Copy link
Contributor

@protyay

This is from the README for this Project. I think we can safely assume we are not building a library here

I think it should not be difficult to find examples where resource server and authorization server roles are performed by single instance. But I am not sure if that is the intention of using the filter.

Even if it's technically possible, it violates what the RFC 6479 outlines as the standard implementation approach.
That's where the confusion lies

I am not sure if RFC will have any endpoint implementation details pertaining to this as Filter and Servlet are JEE specific terms and RFC is supposed to be much more platform / language independent. But if you find any such context in RFC then please share, as it would be interesting to see that.

@dfcoffin

The question I have is which of these issues generates the jwt token?

To my understanding it seems #3 pertains to just generating jwt token and returning it and issue #5 just pertains to authorizing the request. It seems logical to me as #3 or token generation would be required to be protected with many more grant types going forward.

@protyay
Copy link

protyay commented Apr 18, 2020

@dfcoffin
To answer your question, this is from the /token endpoint documentation from RFC

The token endpoint is used by the client to obtain an access token by
presenting its authorization grant or refresh token

I think this issue is responsible for generating the JWT

@dfcoffin
Copy link

@paurav-munshi

I am not sure if RFC will have any endpoint implementation details pertaining to this as Filter and Servlet are JEE specific terms and RFC is supposed to be much more platform / language independent. But if you find any such context in RFC then please share, as it would be interesting to see that.

RFC 6749 Section 4.4.2. Access Token Request states:

The authorization server MUST authenticate the client

The logical way to implement the required client authentication (e.g., Basic Authentication) is as a Servlet filter which is the objective of issue #5

@jgrandja
Copy link
Collaborator

jgrandja commented Apr 20, 2020

The main reason why we want the Token Endpoint to be a Filter instead of a @Controller is because this design decision will allow an application to use another MVC framework instead of Spring Web MVC if that is their preference..

For example, a company may want to leverage the Authorization Server framework provided by this project to build out a OAuth 2.0 / OpenID Connect 1.0 Provider. If all features are implemented as Filter, then the application can use any MVC framework and just plug in Spring Security easily. However, if we start adding @Controller logic then we limit their choice on technology stack.

Of course, we would like applications to use Spring MVC, however, we also need to allow flexibility of choice. This is the primary motive.

As well, Spring Security is all about Filter given that security is a cross cutting concern and such logic is typically implemented in Filter.

The term Endpoint in the spec references doesn't necessarily mean a @Controller. IMO, it could also be a Filter. The key point is that an Endpoint delivers a type of response, whether it's implemented in a Filter or @Controller. The Token Endpoint is a security endpoint so the logical design choice is that it's implemented as a Filter.

@protyay The initial logic for the Token Endpoint is that it should generate a JWT based on the incoming client Authentication. Let's imagine that the Token Endpoint Filter expects a OAuth2ClientAuthentication, that contains the client authenticated in #5. The Token Endpoint will assert on OAuth2ClientAuthentication and the required parameters defined in 4.4. Client Credentials Grant.

@dfcoffin
Copy link

@jgrandja How do you propose to implement the ability for the token response to include additional information besides "access_token", "token_type", and "expires_in" as demonstrated by "example_parameter" in the 4.4.3 Access Token Response example

@jgrandja
Copy link
Collaborator

@dfcoffin It is a very common use case to include custom parameters in a token response. This capability will be enabled. How it's going to be implemented is yet to be determined. The design will get flushed out as we work on it.

@paurav-munshi
Copy link
Contributor

@jgrandja How about implementing the functionality in a more simpler Java class and wrapping the same inside the filter such that the same Java class can be used for the same purpose without the filter. The reason being Filter ( I'm assuming Servlet Filters here) are more of a JEE standard and with the advent of more contemporary frameworks, for e.g Vert.x, it might be more widely re-usable.

@tomvandenberge
Copy link

If I understand it correctly, it means that this project can't use Spring Web MVC? That wasn't clear to me, but it seems a reasonable requirement.

a company may want to leverage the Authorization Server framework provided by this project to build out a OAuth 2.0 / OpenID Connect 1.0 Provider

This confuses me. I was assuming that this project would deliver an authorization server application, implementing OAuth 2.0, possibly including OIDC. A company therefore doesn't have to build out this project to have an OAuth/OIDC provider; it is one already.

When you look at this project as an application instead of a framework, the requirement to not depend on Spring Web MVC is not very useful anymore.

I guess this discussion is a result of different views of what exactly this project will deliver, or how it is going to be used. Maybe it's good to elaborate, to make sure we're all on the same page.

@eicki
Copy link

eicki commented Apr 20, 2020

I think, it is a Spring philosophy to provide toolsets, i.e. a framework (its already defined in its name springframework) not applications. If I want a authorization server application I could choose e.g. Keycloak, but if I already have an application and just want to enable it to act as an authorization server at the same time this project is the way to go in my opinion.
We can nevertheless think of some "standalone-app" module later that is a lightweight authorization server application.

@jgrandja
Copy link
Collaborator

@paurav-munshi

How about implementing the functionality in a more simpler Java class and wrapping the same inside the filter such that the same Java class can be used for the same purpose without the filter.

Most definitely. We should design it in such a way that a user could swap the Filter for a Controller. To allow for this, the collaborating components used by the Filter should be reuseable outside of the Filter as well. We will account for this in the design. Typically, Filter's provide minimal logic and simply control flow to it's collaborating components.

@jgrandja
Copy link
Collaborator

@tomvandenberge

I was assuming that this project would deliver an authorization server application, implementing OAuth 2.0, possibly including OIDC. A company therefore doesn't have to build out this project to have an OAuth/OIDC provider; it is one already

This project WILL NOT deliver an authorization server application/provider. As it states in the README:

The ultimate goal of this project is to replace the Authorization Server support provided by Spring Security OAuth.

Spring Security OAuth is a framework that provides the capability to enable OAuth 2.0 in an application using custom configuration and components. It's up to the user(s) of the application to configure the authorization server with the required features and to customize it to suit their organizations needs.

Having said that, we are thinking about providing a reference implementation built on top of the new framework. There may be server profiles to choose from depending on the type of configuration required. These are early thoughts at this point but our main goal is to allow users to stand up an authorization server easily and with minimal configuration.

@jgrandja
Copy link
Collaborator

jgrandja commented May 6, 2020

@protyay How are things coming along with the PR? Do you have any questions or do you need any help?

@jgrandja
Copy link
Collaborator

I'm going to close this given the Token Endpoint Filter has been implemented in the core module #79.

@jgrandja jgrandja added status: duplicate A duplicate of another issue and removed type: enhancement A general enhancement labels May 29, 2020
@jgrandja jgrandja removed this from the 0.0.1 milestone May 29, 2020
@jgrandja jgrandja self-assigned this May 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: duplicate A duplicate of another issue
Projects
None yet
Development

No branches or pull requests