JWT spring boot 2 - spring

Hi I don't know that I understand correct how it should work with refresh token.
I am creating spring boot backend with angular, and I want to implement JWT.
Currently I am working on backend.
access_token expire in 15 mins
refresh_token: expire date 7 days
When angular sends request with credentials, my spring boot generate jwt token and refresh token. Each refresh token, and access token have different secret(because if they have same secret, someone can access resources with refresh token)
If token expire, angular should access endpoint /refresh_token, on this endpoint send header "Authorization":"Bearer REFRESH_KEY_VALUE", and obtain both new refresh_token, and access_token

Make sure you follow the RFC more details about the same here:
https://datatracker.ietf.org/doc/html/rfc6749#page-10
And also look at the Security Threats and Mitigations here - https://datatracker.ietf.org/doc/html/rfc6750#section-5.1
What you're referring to is Token Disclosure
To protect against token disclosure, confidentiality protection MUST
be applied using TLS [RFC5246] with a ciphersuite that provides
confidentiality and integrity protection. This requires that the
communication interaction between the client and the authorization
server, as well as the interaction between the client and the
resource server, utilize confidentiality and integrity protection.
Since TLS is mandatory to implement and to use with this
specification, it is the preferred approach for preventing token disclosure via the communication channel. For those cases where the
client is prevented from observing the contents of the token, token
encryption MUST be applied in addition to the usage of TLS
protection. As a further defense against token disclosure, the
client MUST validate the TLS certificate chain when making requests
to protected resources, including checking the Certificate Revocation
List (CRL) [RFC5280].

Related

Spring boot API with both Oauth 2.0/OpenID Connect and internal authentication?

I'm having a hard time figuring a good way to implement Oauth 2.0 and OpenID Connect authentication alongside an existing internal email+password authentication for a B2B Web app's API using Spring security.
We have a backend REST API that is a Spring Boot servlet application which currently authenticates users with OAuth 1.0 and the password grant. The front-end is an Angular single-page app through which users must log in with their username and password. The API's /oauth/token endpoint then delivers an opaque access token to be used for fetching secured resources that are then displayed within the app.
We'd like to add the possibility to log in using external authentication with OpenID connect, which is a perfect opportunity for switching to OAuth 2.0 and JWT tokens. Our API would then accept JWT tokens it delivered as well as external JWT tokens emitted by accepted issuers.
Reading and validating JWT tokens won't be a problem using Spring security's OAuth Resource Server. However things get complicated with how to make the classic username+password login flow work with JWT tokens.
We thought about delivering JWT access tokens the same way we used to with our old OAuth 1.0 tokens. The thing is, newer OAuth specifications advise against using the password grant, plus it simply isn't supported in the Spring authorization server project we're planning to use. The authorization-code flow w/ PKCE seems like too much for this case as we do not want the back-end API to render a login form but use credentials entered in the existing login form that is part of the single-page app.
I've read a lot about not using OAuth for 1st party login since its primary use is for external authentication, but again, that doesn't apply since we also want 3rd party authentication.
What would be a secure way to implement a Spring boot authorization server that can deliver JWT access tokens to a 1st party client in exchange for a user's credentials, all this using the existing log in page, and given the password grant type no longer being supported?
I thought about implementing a preliminary step that would be a POST request with Basic authentication to a /login endpoint that just returns a 200 HTTP status, then proceeding to the /oauth2/authorize request that would deliver the authorization code immediately without redirecting since my session is authenticated.
I'll be happy to provide more details if needed. Here are the resources I'm using for this project.
What about setting up an authorization-server capable of identity federation?
In such configuration, the authorization-server is responsible for providing with identities, proxying one or more sources (your existing user database for instance, plus maybe Google, Facebook, Github, etc.)
Keycloak does it for instance.
From the client point of view (your Angular app), the authorization-server is used to get:
access-token: put in Authorization header of requests to secured resource-server(s) (can be a JWT or an opaque string, doesn't matter, clients should not try to extract data from access-tokens)
refresh-token: send to authorization-server to renew access-token before it expires
id-token: get user-profile data (email, username, profile picture, etc.)
You should have a look at https://github.com/damienbod/angular-auth-oidc-client for connecting an Angular app to an OIDC authorization-server.
From resource-server point of view, access-tokens are the source ofr setting-up security-context, either by decoding and validating a JWT locally or with token introspection on authorization-server.
Have a look at those tutorials for such resource-servers configuration.

Authentication patterns in microservices

There are several approaches for managing authentication in microservices including service to service authentication. I want to understand which approach is better.
When a user logs in to the system auth-service call is happening and the auth-service returns an opaque token (not JWT), then each API call contains that opaque token Gateway validates the token through the auth-service generates a new JWT token for downstream services. So downstream services will not have to call auth-service each time to validate the token.
From the beginning auth-service will generate a JWT token.
2.1. Gateway will validate and pass it through downstream services and all services will use the same token
2.2. Gateway validates and generates a new token each time, and also downstream services do the same.
Each approach has its pros and cons.
Questions:
Approach 1. Gateway each time needs to doo auth-service call to validate?
Approach 2. What will be the expiration time for JWT tokens? Who needs to handle the expirations, what token expires in between who needs to regenerate it again? JWT tokens must be short-lived, so whether it will not affect client behavior, or refresh tokens should come in the picture here.
So I am confused about which approach is good,or are there other approaches.Please advise me.
JWTs should be avoided to be exposed to the outside world since these could potentially include sensitive information in custom claims. Especially if you work in a large company, where you can't keep track of what ends up in different claims.
So if using opague tokens (which you should) the gateway should verify and exchange the token to a JWT that can be used internally inside your network.
All services SHOULD always be setup with zero trust in mind.
All services should if possible fetch JWKs to verify the incoming JWTs. And these JWKs should be rotated on a regular basis.
This is to avoid that if a malicious actor gets access to the internal network he shouldnt be able to do any request to any service just because he has passed the gateway.
When it comes to expiration times, these should be set by the issuer and should be kept short because one of the big problems is that its easy to issue a token, but harder to revoke one.
The flow is usually as such:
Client logs in and gets issued a AT (access token) and a RT (refresh token)
Client presents opague AT token to a service in the backend
Gateway exchanges the opague token for a JWT
Gateway passes the JWT to the service that is requested
The resource server validates the JWT
if request is denied a httpstatus of 401 is returned to the calling client
the client receives the 401 and then presents its refresh to the issuer that will issue a new AT token.
request is redone with the new AT token.

JWT with JDBC token store vs JSESSION ID

I have implemented a spring boot application which does authentication and authorization using Spring OAuth2.
I am using JDBC token store to main the token issued to the client for performing Custom claim verification and some other user status verification during application run-time.
The question is, since i had used traditional JSESSIONID with CSRF token, i cannot find any advantage with the new OAuth standards because after login i would store the user details in the session and retrieve it whenever needed similarly for OAuth i store the User details in the JWT token itself and decode the token every time to get the user information, also i need to hit the database anyway for custom claim verification such as JTI verification .
Everyone says JWT is for stateless application but with JDBC token store i'm holding all the token that is issued to each client. Also there is an additional overhead to purge the expired token which will be done automatically with Session. Also i'm using refresh token as the way to implement session timeout.
Therefore can anyone explain me, when should i use JSESSIONID and when to use JWT ? My application is running on AWS architecture.
From my experience, cookie-based authentication sufficiently complicates scaling and load-balancing. If you have authenticated via the first service replica, your cookie will be not appliable to another replica, cause all sessions are stored in memory. So, if you want to scale your service in the future, session-based authentication can make things much more complex.

what exactly is sent from the resource server to the authentication server In spring security oauth2 during token validation

I understand that a resource server will make a call to the authentication server with a token to confirm that it is valid.
However is this token the same Cookie: JSESSIONID?
Oauth 2.0 Bearer tokens are of two types - General tokens(e.g like java uuid string) and JWT tokens.
General tokens will be stored in the authorization server token store along with their scopes, expiry, client ID, UserId and other related information. When client sends request to resource server, Resource server need to reach out authorization server(Spring oauth 2.0) for bearer token validation.
JWT tokens contains information about its expiry along other user information and self sufficient to work in stateless sessions, Here we don't need to validate oauth 2.0 JWT tokens from authorization server.
JSESSIONID Cookie is created by spring security by default, its not related to Bearer token authorization.
Well the standard solution is an introspection request, as in step 14 of this post: https://authguidance.com/2017/09/26/basicspa-oauthworkflow/
Not all solutions are standards based though - and I always recommend capturing the HTTP traffic

Token authentication and SSL

I'm relatively new to this area of securing API. Most of my career was in developing internal products for the use of the organization, or joining a product that has already implemented security (which usually does not change)
When reading about JWT and Identity server, I understood the role of signing and the need to separate authorization and authentication. But, one thing strikes me as odd:
If my user is about to get a signed token and use it to authenticate himself, and there is a "Man in the middle", listening and copying that token, could he impersonate my user? (I believe the answer is yes)
So my best option here is to use SSL on every call to my API. The token being temporary and all is not much less of a threat to security.
So, my question here is:
If I end up using SSL on my API calls, what is the signing good for? with SSL the traffic is hidden anyway and no one could tamper with it. The browser can possibly use the username and password as plain text and they won't be exposed.
What am I missing here?
I think all boils down to what purpose JWT serves in OpenID Connect protocol (OIDC).
In OIDC, ID token is a JWT. And if you go through RFC7519 - JSON Web Token, then you come across Trust Decisions section.
The contents of a JWT cannot be relied upon in a trust decision
unless its contents have been cryptographically secured and bound to
the context necessary for the trust decision
From OIDC perspective, trust decision is to authenticate the end user based on claims contained in the ID token. This can be only done if validation adhere to JWT specification. So basically it is a requirement by OIDC protocol and JWT specification.
Now about SSL. OIDC contains several other calls required to obtain final token response. These calls contain client identifiers, secrets and authorization code (depending on the flow). OIDC is built on OAuth 2.0 and OAuth 2.0 mandate SSL (TLS being the new name). Thus OIDC too require SSL.
In combination, SSL (TLS) prevents attacks during request and responses flow in wire. And JWT's signature guarantee token's authenticity independent of how it was received or which component of your application process it.

Resources