What I'm trying to do
Right now I'm working on a Java Spring Backend for a Both which manages the request he gets from a NLP from api.ai and gives back corresponding information. Now I'd like to interact with different services that use OAuth2 to get information/data from there as well.
What I did so far
I have added my credentials for the service in my application.properties file. But only found a solution that a user can for example log-in with his facebook credentials on my service.
But I need to have my service to authenticate on the other service (with the given credentials from my properties file), to gather data from there.
Do you guys know a solution, tipps, tricks for that?
As I understand the logic should be following.
As you have SSO (OAuth2 based) you need to login just once and get token(s) from OAuth2 service (access token and refresh token). The access token is included in the request headers when you call any of your services.
Now Service1 must call Service2 using the same auth info.
In the Service1 you call OAuth2 service to check whether the token is valid. If yes all you need is to use the same token to call Service2.
So just extract the token from request headers and add to the headers of request you send to Service2. Could be done e.g. by adding a Filter and storing the auth info in a ThreadLocal variable (or inheritable ThreadLocal if you generate new threads by e.g. running Jobs).
Service2 in turn also checks the token by calling OAuth2 service but the token is valid.
For me that's all you need.
Related
My quarkus backend is calling a rest web service which requires an access token. The access token is generated using client id, client secret and grant type client credentials. The token is valid for a couple of days.
This quarkus backend then propagates the data to an angular frontend.
I have a couple of questions:
Is there an out of the box implementation from Quarkus framework?
If not, please guide me if I should use httpclient or any other library for getting the access token.
How to check for refresh token?
How to save the access token, so that it can be used for other requests by other users?
Otherwise I end up generating an access token every time a user calls the rest service.
Since there is no answer, I will write here how I implemented this:
I use a java.net.http.httpclient to call the oauth server for getting the token with the client id and secret.
I cache the token using quarkus-cache and when the token expires, the quarkus-cache is invalidated and rebuilt with the new token.
Suggestions or better solutions are welcome.
I have gone through multiple blog posts and StackOverflow questions before writing my own. I have multiple queries and none of the posts answer them.
I am using Keycloak Spring Security Adapter to secure my legacy Spring application. I referred to the keycloak documentation here and was able to have OAuth flow running for me. I am using Client Id and Secret as Client Authenticator.
For eg: Access to localhost:8080/about.htm will redirect me to keycloak login screen and after successful authentication, I will be able to view my page. I am also using the below code to read the user details from the token,
KeycloakPrincipal<KeycloakSecurityContext> kp = (KeycloakPrincipal<KeycloakSecurityContext>) auth.getPrincipal();
IDToken idToken = kp.getKeycloakSecurityContext().getIdToken();
user.setUsername(idToken.getPreferredUsername());
Now when I test this application using postman and modify the generated access token, obviously the server gives an error. Ref : How to test application using postman.
However, this is the flow :
Client sends a request to the resource server, resource server checks for a token - if it exists, the client does the validation. If it doesn’t exist or is invalid, it redirects to the authorization server (KC).
My question is,
Who is validating this token? How does postman flow throw an error
if I fiddle with the token?
Do I really need to write a JwtTokenValidator in my application for
each request? Won't that be overkill?
If I use Client Authenticator as Signed Jwt with client secret, will this validation still be required? I am not using it as it introduces latency.
Please assist.
Answer to #1:
When you use any Keycloak adapters in your application (in your case the Spring adapter for Keycloak), that's the one who does the validation and redirects to the login if necessary. As part of the validation, it checks the signature of the token issued by Keycloak. So when you fiddle with the token, the signature doesn't match, hence it throws an error.
Answer to #2
No, you shouldn't need to implement a JwtTokenValidator. The adapter does it for you and a request should reach your endpoint/URL only if it has a valid token. You may only need to do that if you have a special requirements about validating the token (e.g. checking specific claim in the token against some service). Otherwise, you can safely use the claims in the token you received from the KeycloakSecurityContext. You can even setup authorization based on your URL patterns and Keycloak will enforce them too and allow the request to pass if user has necessary roles (like this example).
Answer to #3:
That option only changes the method used to authenticate your app to the Keycloak and has nothing to do with the user's token validation inside your app. In your current setup, when your app wants to communicate with Keycloak (e.g. to exchange auth code with auth token), it authenticate itself to Keycloak with a client-id/client-secret pair (otherwise Keycloak would not know it's your app and will reject the request).
If you choose the "Signed Jwt with Client Secret" option, your client can not just use a client-secret to authenticate to Keycloak. It should support the RFC7523 specification. So it's quite complex in compare with a simple clien-secret approach. In an environment in which you trust your clients (e.g. they're all known apps developed inside the company and you're not going to support public clients to join your Keycloak and use its services) it's quite common and safe to use client-secret approach.
I have access to a web application which has a link to another application I'm developing. When that link is clicked the URL is filled with two parameters: user, and token.
This token is generated per every user login on that very same web application.
I want to use that token and user to authenticate someone in the application I'm developing!
I have access to the source app's database in order to query against the token and username.
However I need help finding a way to implement this logic with Spring-Boot. Do I need a custom filter / authentication provider? How to wire these things up with Spring?
I want to stick to the framework rather than developing my own solution for this.
TL;DR: I need help securing a RESTful controller with a token I obtain through GET
Thank you!
Yes, you could write filter to authenticate token.
If you want make architecture a bit better I would recommend creating gateway (i.e. Zuul) and invoke second application through gateway. Implement gateway to authenticate requests. In my architecture I create separate Auth component to generate token and validate token. Gateway could call Auth to validate token.
I have a web application that provides several rest services (Jersey). Most of the endpoints are secured by BASIC authentification. Further more I use SSL for transport and demand POSTs for every call.
The clients/consumers are android apps.
So far so good. The only service that seems to be vulnerable is the registration. It's the 'first' service to call and a user does not exist yet. So I cannot use OAuth, etc. I also have to keep the endpoint easy accessible to enable the user to regster.
How do I secure this service, so it's not spammed by a bot flooding my database?
How about these?
Use a registration link with a token in the request parameter. Ensure that the tokens expire after sometime. You could create a token endpoint url as well for a client to get a valid token.
Use a custom header or a dynamic custom header in your request. Additionally, you could check for a dynamic custom header to validate the request's authenticity.
Use registration confirmation workflows, such as an email / text verification as soon the registration is done. Run a process every day to delete any user accounts, which are not validated in say x days.
I do not think you can really secure the registration URL in a HTTP way. IMHO, anyone who has the registration url can be a right guy trying to register. So if you ask me, option 3 is better than others.
I am planing to write an API for a mobile app. To lower the barrier for first time users i do not want a login screen on the first start. So what I want is, if the app notices it is it's first start it should register itself:
/register
A standard User should be generated like Name: GuestXX43, Authtoken XX43-58asda5-54asd, some additional Data
The user is now able to make other endpoint request due to its auth token.
But how do I check for the correct auth token on every Request?
/user [Update]
the user is also able to update his username and password to reloggin on another Device.
Which auth method will suite these thoughts, is there any doubt using this kind of auth flow?
Thanks guys
Are you using Google Cloud Endpoints? If the user credentials is set in some header, you can retrieve it in the backend via injecting HttpServletRequest in Java or check HTTP_YOUR_HEADER_NAME environment variables in Python.
Also you can try custom authenticator if you uses Java; this post can be relevant: Google Cloud Endpoints and user's authentication.