How to implement Oauth2 in spring boot? - java

I'm learning Ouath2 implementation in spring boot below way.
I want user to authorize himself first and then get a token, once get a token I want user to send that token with its REST API request to get resources.
Then resource server will verify the token and once valid will release the resource back to user request.
I know there are many examples and studies are available, but what I have observed that, most of the example are using GOOGLE, FACEBOOK etc to authenticate their user, that's not gonna help to understand my learning to develop everything manually for better understanding.
My ask is, Is anyone can share any example or references where I have control over (user authentication process + release token) and once user has token, then on resource server (validate the token with authorization server + full fill user request) I could implement token validation and return result ?
I'm want to do this authentication mechanism by myself for b. Is there any open source example is available just for learning purpose ?
All suggestions are welcome

The name of the thing your are looking for is Keycloak or Okta (these two are most popular). There are a lot of tutorials of course.

Related

Keycloak JWT Validation using Java Spring Security + KC Adapter

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.

Spring Boot - Token authentication

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.

Secure Rest-Service before user authentification

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.

Java OAuth2 Provider Implementation | Custom Errors

I have searched high and low for the answer to this question and now I'm reaching out to the community.
I'm trying to build an OAuth2 access token endpoint in Java.
I'll be implementing the resource owner credentials grant type to return an access token. (specifying end-user's username/password to get an access token)
During authentication of the user credentials, a number of rules could prevent the user from having access to my web service, such as the user account being locked.
The OAuth2 RFC says that errors must be returned as follows:
{ "error":"invalid_request", "error_description":"description", "error_uri":"some_link" }
It's also my understanding that the OAuth spec lists standard error codes and that you should avoid custom error codes in the response, like {"error":"account_locked"}; however, I've seen some API providers do this.
I need the clients of this API to be able to read an error code in the response to know when the account is locked. (or other specific scenarios)
Now my questions are:
Does anyone here have the experience to suggest how should this scenario be implemented?
Should I implement custom error codes?
Should I forget the OAuth2 spec and just build a /token endpoint that does the same thing: authenticates the user, generates the token, and returns my API's standard error response?
I don't have an exactly same senario. But I won't use custom error codes since it violates OAuth2. Instead, I may consider using the "error_description" as the error-code field in this case; Or I can add an biz_error_code field.
Yes, you can forget OAuth2, which is not flexible in terms of http status code and error_code. But you will end up building something very similar with OAuth2's 'password' grant_type, such as an access token and a refresh token.

Appengine Custom Authentication

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.

Categories

Resources