Support for multiple ways to sign into Spring security - spring-boot

So we are building an application which has to support two ways of creating a new account.
user creates an account with a email and password combination
user adds an Authorization header with a JWT token from a trusted third party. This JWT is verified and contains the necessary information such as email to create a user in our system.
Creating a user this way works fine. However, I am not sure how to deal with the subsequent authentication. The current system uses session-based authentication.
Question: A user that created an account with the JWT should also be able to login without a password. I can think of two way to achieve this:
Validate the JWT and manually start a session. But how can I start a session manually without a password?
Add a filter to the Spring Security Chain that checks whether a JWT is present. If so it adds the user the the security context. If no JWT is present it requires the user provide a valid email, password combination. Any resources on how two do this conditional chaining?
Any hint for an advantage or disadvantage for the two methods is appreciated.

Related

Userless Automated server to server Oauth2 2 legged authentication to Gmail

I've found plenty of information on implementing Oauth2 using a user authorization step, but I'm trying to run a container that automatically scrapes a gmail inbox for attachments transforms them, and exports to prometheus, and I'm having trouble figuring out how to implement this library: https://pkg.go.dev/golang.org/x/oauth2/clientcredentials#Config or any other for that matter to retrieve a token without involving a manual user step.
Will doing this in Go require writing direct API calls since I can't find an existing library to handle this scenario? Would it make more sense to create a Google App password and use generic user/pass SMTP authentication?
First off i understand what you are trying to do.
You have a backend system running in a container which will access a single gmail account and process the emails.
Now you need to understand the limitations of the API you are working with.
There are two types of authorization used to access private user data
service account - server to server interaction only works with workspace domains. No authorization popup required.
Oauth2 - authorize normal user gmail accounts, requires user interaction to authorize the consent screen
If you do not have a workspace account and this is a normal gmail user then you have no choice you must use Oauth2, which will require that a user authorize the application at least once.
Using Oauth2 you can request offline access and receive a refresh token which you can use to request new access tokens when ever you wish. The catch is that your application will need to be in production and verified, because your refresh token will only work for seven days and then it will expire. To fix this and get a refresh token that does not expire means that your application must in production and verified. This means you need to go though Googles verification process with a restricted gmail scope which requires third party security check and costs between 15k - 75k depending upon your application.
I understand that this is a single user system but that does not mean that you still need to go though verification. When google added the need for application verification they did not take into account single user systems like yours.
Option
Have you considered going directly though the SMPT server instead of using the Gmail api? If you use an apps password you should bypass everything by loging in using the login and the apps password.

Connect to 3rd party rest api with oAuth2 security server when using own oauth2 implementing

Im trying to find some best practices on how to solve my problem.
I have a microservice application with oauth2 and firebase for authentication and authorization.
Our application needs to connect to a 3rd party rest api which is secured with oauth2 as well.
Is it possible to integrate both implementations or do i need to make my own solution?
One of my co-workers implemented the authorization-code flow needed to access the api and we basicly store access and refresh_tokens in the database to access this 3rd party api. But it doesn't feel right, i cant find any best practices either, can anyone help me out?
What your co-worker implemented is pretty typical: separating out the authentication and authorization for your own application (which you manage with Firebase) from your users authorizing your use of the 3rd party API.
Here are some best practices you should be following when implementing your OAuth flow:
Use the state parameter to avoid CSRF attacks. Store it in your database and compare the callback state with the one that you randomly generated for the user
Encrypt access and refresh tokens. Refresh tokens in particular provide long-lived access
Verify that the scope you asked for is the scope that was returned: some providers allow users to adjust the permissions, which can lead to unexpected errors
Make sure your refresh tokens don't expire. Check with the provider's docs to see how refresh tokens are deauthorized. Some are time-based, some are based on new refresh tokens being issued, but in any case, make sure your refresh token stays valid, as if it is not, you must get the user to re-authorize your application
You can also use a managed OAuth provider to abstract away all these elements. Xkit, which I work on, integrates with Firebase Authentication so your users can authorize your app, and you can retrieve each user's tokens with one API call.

Authorization and microservices

Our system is moving from a monolithic to a microservice architecture.
The microservice architecture comes with technical challenges that we need to address and one of them is AuthN/AuthZ.
Our approach is to have an authentication service that would authenticate users and generate access/refresh tokens (JWTs).
Access tokens would then be passed in request header through the chain of microservices such that each microservice just have to validate the token to determine the user has been successfully authenticated.
For the AuthZ part, permission enforcement is done in the microservice itself. My questions are related to AuthZ.
To illustrate the talk, let’s take a specific example of a receptionist who wants to register a new member to his fidelity program, for instance from a Web application.
To support this use case, let’s assume the system has 2 microservices, the ReceptionService and the MemberService.
The ReceptionService offers one REST API to initiate the member registration flow. It requires user permission “registration” to allow execution.
The MemberService offers one REST API to create a new member resource which is protected by CRUD permissions.
A request flow would be:
The web application, on which the user has previously logged in, sends a member registration request to the ReceptionService API including the user access token in the header.
The ReceptionService validates the user token, ensures user is granted with permission “registration”, does whatever business logic it needs to do, and finally sends a member creation request to the MemberService API including the user access token in the header.
The MemberService validates the user token, ensures user is granted with permission “member.create”, and finally creates the member.
To design a solution for such case, my team worked on the following assumptions/prerequisites:
A microservice must always enforce permission (at least for significant API operation such as creating a member). Thus the CRUD permissions on the MemberService in the example above even if Products Managers might only require the top-level “registration” permission.
A user who is able to start a use case because it has the “top-level”
permission must be able to complete it. Meaning It shall not get
errors because he is lacking another permission from somewhere in the
underlying services’ call chain.
Admin users shall not have to understand the chain of permissions
that is required to perform a use case. In our example, Admins should
be able to provide users only with the “registration” permission.
To be able to complete the above example, there are 2 different permissions to be assigned to the user, which breaks some of our assumptions/prerequisites. To overcome that, one of my colleague proposed to consider declaring microservices as identities/users in our AuthN system so that they could be assigned with the appropriate permissions. The user token initially provided would then be replaced by participating services token among the call chain.
To come back to the example, the new request flow would be:
The web application, on which the user has previously logged in,
sends a member registration request to the ReceptionService API
including the user access token in the header.
The ReceptionService validates the user token, ensures user is
granted with permission “registration”, does whatever business logic
it needs to do, and finally sends a member creation request to the
MemberService API including its own service token in the header (and
so replacing the original user token).
The MemberService validates the service token, ensures service is
granted with permission “member.create”, and finally creates the
member.
With this solution, service’s identities in the AuthN system would be flagged in a way that they are filtered from an Admin user managing permission assignments. Permission assignments to services identities would be pre-defined with no possibility for a user to configure it. While it fulfills our assumptions/pre-requisites, I have few concerns about this approach:
When dealing with the “who did what” (audit), user identity and
service identity provided in the tokens would be listed
indifferently. In our example, the RegistrationService would audit
the actual user who initiated the operation but the MemberService
would audit that the operation was performed by the
“RegistrationService”. In reporting scenarios, it means I would need
to reconciliate audit from both systems to determine “who actually
did create the member” using somehow a correlation ID.
While I understand the need to create an identity for a system
component in scenarios which do not involve an actual user (automated
batch/third party access ..), I am not comfortable with replacing the
user token with a service token in scenarios where a user actually
initiated the use case. Is that a standard design pattern?
Could it be that some of our assumptions/prerequisites just wrong?
For instance, is it really a security hole that some microservices do
not enforce permission even if they are only accessed by others
controlled microservices in a safe environment? Assuming the answer
to the latter is “no, it would not be a security hole”, then what if
tomorrow, I need to make the MemberService API also accessible
outside of the safe environment (for instance, because I make it
available to a third party). I would most likely need to add a
permission on it, which would break my registration flow.
Is it wrong to say we do want Admin users to know which set of
permissions are required for a use case and that we should rather
build the system so it gracefully handles failures due to lack of one
permission in the call chain (maybe using Sagas and compensation
routines)?
Any comment or links to resources would be greatly appreciated.
Thanks!
Each service should own it's own permission-schema, but I would recommend you using Service Mesh to not Authenticate user throughout each hop/Microservice.

Strapi - anonymous browsing

I'm developing a mobile app which will allow users to browse without signing up. I would like to have all my endpoints secured via token.
How would we go about allowing anonymous browsing? i.e. provide a token to anonymous users.
Not sure to understand your case, why do you need a token if your users aren't registered and your API opens to everyone?
The authentication system of Strapi has been built to only send token to registered users. However, the easiest way to make it work for you is to register every visitor coming in your app based on their IP or something unique as a username and set the same password for each one of them. Then, every time the user comes back, you can call the /auth/local URL to sign-in the user and get the token or use the token stored in the local storage.

Using scopes as roles in Spring Security OAuth2 (provider)

Let's consider a fairly simple hypothetical application where users can read or write posts.
Some users can read and write articles while some others can only read them. With Spring Security (3.2.1) I modeled this by having 2 roles:
ROLE_WRITE: this role grants users access to writing posts.
ROLE_READ: this role grants users access to reading posts.
Implementing this with Spring security is fairly straightforward...
Now I want to also allow third-party apps to read and write posts on behalf of users by implementing an OAuth2 provider using Spring Security OAuth (version 2.0.0.M3 ATM).
During the authorization step, the app asks the user whether they are willing to grant the right to read and/or write posts on their behalf. The user here is granting scopes here (not roles).
Then when the OAuth2 consumer calls my REST API, Spring Sec OAuth authorizes the token granted and creates an authentication containing the user with all their roles and only the scopes granted.
The problem (and the question) is that I now have to write different security logic depending on whether the API is called by a user normally authenticated (just check the roles) or whether it's called through OAuth2 (check roles + scopes).
Is it possible to "merge" the concepts of roles and scopes in Spring Security OAuth2 so that during the authorization step, the user grants the app a subset of the roles they have (and have the OAuth2 authentication only report these in the granted authorities)? That way when the 3rd party app makes an API call, the roles on the authentication are the ones granted? That way I don't have to write any OAuth2 specific security logic.
Scopes (and roles) are arbitrary strings, so there is no problem if you want to make then the same. To make the access rule declarations identical you could write an ExpressionHandler that tested authorities or scopes with the same values depending on the type of Authentication it found.
A different approach suggests itself after you read the comments: add a custom TokenStore or ResourceServerTokenServices. These are easily accessible extension points and would permit modifying the OAuth2Authentication so that its granted authorities were the same as the scopes.
My preference, however, is to control the allowed scopes using a OAuth2RequestFactory, limiting them at the point of the token grant to values that are consistent with the user's authorities.
You can configure your own AccessTokenConverter (mainly for JWT) and extract the claims you want from the JWT access token and generate an Authority object. Just define a Bean factory that return an AccessTokenConverter

Resources