Spring Boot OAuth2 - Remember given Authorization - java

i'm currently working on a OAuth2 Authorization Server using Spring Boot and the Spring Security OAuth2 Autoconfigure library.
Everything works so far except the fact that I need to authorize the client every time to access my protected resources. Is there any way to suppress the prompt or remember that i've already authorized the client?
Adding &prompt=none to the request params of my URL didn't work as expected.
I already tried to add a custom AuthorizationRequestResolver and adding prompt=none to every request, but that didn't work also.
Thank you in advance.

Usually after you are authorized by the authorization server, as a result you get an access token.
The resource server verifies against the access token to determine your client has the right to retrieve the requested resources.
With this background, one possible case is that:
Your client doesn't store the access token. So that everytime it hits the resource server, the resource server redirects the client to the authorization server to get the access token.
A solution of this is your client can store the access token. For the subsequent requests to the resources server, the access token has to be provided in an expected way. (like Aurthorization request header)
You may also find storing a refresh token is useful. Since there is no much background about your client app, cannot give a concrete recommendation for you.
If this is the case, you can log your outgoing request from the client to the resources server, you will see the access token missing in your request.

Related

Authorization code flow - how to get Code parameter value

I've implemented an application that redirects to the wso2 identity server login page. If the login is successfull the user is redirected to a page where he can read his profile details.
Based on his role he can perform certain action, like create a new user.
I've implemented an API (http://localhost:8080/add-user) that calls this URL ( https://localhost:9443/t/carbon.super/oauth2/token) to generate the access token with the desired scope (for example internal_user_mgt_create) that I need in order to call
the wso2 SCIM2.0 API (https://is.docs.wso2.com/en/latest/apis/scim2-rest-apis/#/Users%20Endpoint/createUser).
Everything works if I use grant_type=password and I use the user credentials to generate the access token to call the wso2 SCIM2.0 API, but I want to use "authorization_code" as grant_type to avoid sending user credentials in my application.
How can I do that? And I know that one of the parameters that I need to use this flow is "code", where can I get its value?
You can configure authorization code grant in your application by selecting the Code from the Allowed Grant Types list OAuth/OpenID Connect Configuration in your application. [1]
When using the auth code grant your application needs to wso2 authorize endpoint to obtain the authorization code Using this authorization token and client secret you can obtain the access that is capable of calling the scim endpoint.
Refer to following documents for more information
[1]. https://is.docs.wso2.com/en/latest/guides/access-delegation/authorization-code/
[2]. https://medium.com/identity-beyond-borders/generating-access-tokens-using-wso2-identity-server-4d8c084a3bf5
It's harder to provide an exact answer to this question without knowing more details about the app and the flow you'd expect your users to go. However, it'd be much easier if you have a better understanding of the OAuth2 code grant type. The following is the basic flow.
The user accesses your application through a web browser.
Your application redirects the user to the identity server, with the following parameters in the request.
client_id=xxx
response_type=code
redirect_uri=yyy - Location in your application where you want to get the authz code. This needs to be registered with the IS service provider beforehand.
scopes
The IS prompts the user to log in.
The IS then redirects the user to the given redirect URI, with the authorization code.
Once the code is received by the client, it makes a back channel call to the token endpoint of the IS (https://localhost:9443/t/carbon.super/oauth2/token) with the following parameters.
grant_type=authorization_code
client_id=xxx
client_secret=zzz
code=ccc
IS validates the code and issues an access token.
Read more on OAuth2 here.
Now, if you're getting the "Inactive authorization code" error, your application might already be calling the token endpoint with the code received, before you call your add-user API.
Ideally, your add-user API shouldn't call the token endpoint at all. You should call the token endpoint from your application, get an access token and pass that to the add-user API if needed. Or you can directly call the SCIM API from your application itself.
I hope this helps!

Spring Boot with common Authentication

I am trying to set up authentication server for spring boot application. I have multiple microservices application. Let say hospitals, patients, reports applications. I have each of microservices service application to be authenticated before allowing user to access the resources.
Can I know how can I have common authentication logic as a separate application. let say authentication application. I am planning to us (spring security with Auth 2.0 and JWT token).
For example:
When user tries access hospital dashboard page, we will check the user is authenticated
First we need to check whether user is authentication if not I need
to redirect to login service in authentication application.
Once user is logged in, then when he try to access dashboard we will
check the token is valid. If valid then allow user to access the
dashboard service.
Now user try to access patient details which is there in patient.war as a separate project, as the user already logged in we need to valid token, then we need to allow access to resources API what he is trying to access. If token is invalid then we need to redirect to login page.
Question:
I have gone through some example they have authentication server and resource server as separate application. i.e #EnableAuthenticationServer and #EnableResourceServer. But I have noted this got deprecated in latest spring boot version if I am right. Please correct me if I am wrong.
How can I have authentication functionality as common war file and let the other resource server access it before allowing the user to access the reset service API?
Which is the right way to build a microservice application?
I need some experts help to understand the best approach we need to implement authentication and authorization in latest spring boot version.
This is a relatively older question but I'll answer since it may help others.
For any microservices-based architecture, the api gateway is an important aspect and it should be there.
All your microservices will be hiding behind the gateway and any calls made to the downstream services (hospitals, patients etc) will go through the gateway.
This gives you multiple advantages.
You can add login (authentication) functionality in the gateway
You can put rate limiter to avoid DOS attacks
A single point of entry for the outside world so your clients don't neet to know the URL of each microservice
Now, the way it works is:
The client sends username/password or client_id/client_secret to the /login endpoint which is inside the gateway (for example GatewayController)
Gateway sends credentials to an "Auth-Service" which authenticates the user from a db or anywhere and creates a JWT (Oauth token)
Gateway returns the jwt back to the client
Client calls the, let's say, /patients endpoint through gateway with the jwt as header "Authorization" parameter
Gateway -> Auth-Service (To validate the token)
If invalid, 403 forbidden is sent. Otherwise, request is forwarded to the downstream service (in this case Patients-Service)
Patients-Service sends the jwt token to Auth-Service to get permissions from inside the token since we know that the token has already been validated.
Once the permissions list is received, the Patients-Service matches them with the permissions mentioned on each api (for example PatientsController)
If any permission matches, the response is served. If not, 403 forbidden is served.
To make it more clear, Auth-Service is called once when the call is for login(authentication). Auth-Service is called twice for all other api calls(validate + permissions).

Is it possible to get authorization_code in OAuth 2.0 without web browser in Java?

As I understand, in authorization code flow we need to get authorization code and use it to get token after. We can get this code only when user confirms specified access. After that browser redirects us to redirect_uri and response will contain authorization code as parameter. So, the question: is it possible to get this authorization code without browser or any self made UI? Can we get it in application after correct request to, for example https://mysite.tuz/authorize ?
As you are using authorization code flow, the client requires a user agent (i.e browser or mobile app) to get the authorization code from the authorization server.
The whole purpose of using authorization code is that it can be passed via the user's web browser (user agent) instead of passing the access tokens directly via the web browser (user agent) which is not desired. Using authorization code,the Client then can directly retrieve an Access Token from the authorization server.
So the user agent is required to get the authorization code and act as an intermediary between client and authorization server.
If you do not require a browser then authorization code flow may not the correct choice. OAuth 2.0 supports several different grants i.e ways of retrieving an Access Token. Deciding which one is suited for your case depends mostly on your Client's type.
This might help you in deciding which flow to use
https://auth0.com/docs/api-auth/which-oauth-flow-to-use
You should use client credentials to obtain token without browser or any client. But if you need to use user credentials to get access token and id token of the user without browser or mobile app you need to implement you own client which will do the necessary logic for you and fetch the token for you. I already did it in java for the testing purpose. I don't know why you need to do it but you can implement your own client in almost any programming language . But in case you will decide to go this way you have to handle lot of things.
I expect your authorization server requires Proof-Key for Code
Exchange (PKCE) - so first of all before you start to communication
with server you have to create code verifier and code challenge
(google can help you with that :) in java it is quite simple)
Then you should start communication with server sending get request to url which ends with 'auth' you should send query params as: response_type (which is 'authorization_code' in your case), redirect_uri, client_id, code_verifier, code_challenge, scope, code_challenge_method (probably 'S256')
Then you receive I think two redirects from server so it is better to have some client in java which will automatically call those redirects. I used apache http client for my implementation. It has lot of features.
After successful redirect server will return login page to your client. It depends on authorization server but in this page you should put the data as username and password and submit the page. I have simply parsed the returned page and get the url for user authentication from it and simply make post request to that url with user credentials data sent in encoded form entity. In apache http client you will have all cookies from previous communication set (until you close the client) since apache http client automatically set all cookies returned in previous communication from server.
After make authentication request server will send you two redirects and you can store those redirects int http client context which you will provide for http client when you call authentication url.
In the last redirect there will be query parameter sent be server named "CODE" this is really important for you since you will use it to get token from the server
And finally you have to make one last post request to authorization server with url ended as token. So make a post request with GRANT_TYPE, REDIRECT_URI, CODE (you received in previous redirect), CLIENT_ID, CODE_VERIFIER (you have generated at the beginning);
Then authorization server will send you token and that's all

How to achieve login in java consuming a web service?

I have a project in java which utilize j_security_check and ldap for authentication. Now my employer want to change it to an authentication using a webservice provided . What they gave me is actually a link as shown below
"http://11.111.111.111/ADManager/ADlogin.asmx"
I am a total newbie to java and webservice.All I know is if we provide some data to a webservice it will give a response. my doubts are
Is it possible to create a login consuming that link they provided?
Should I ask them for more info?
Is it posible to replace the j_security_check and ldap already configured in my java project?
P.S : The one who assigned me this task doesn't seems to have much knowledge either.
The short answer is you can.
You need to do the following:
Each web resource is protected by a (servlet) filter. This filter checks each incoming request and validates the token which needs to be on the http header. If the token is valid then the request is served. If the token is invalid the filter is going to send back http 401 unauthorized. Then redirect to the loin page.
Login with rest service:
1) Create a custom login page with username/password field.
2) Create a rest web service, receives username/password. It will check the credentials against an external access management infrastructure like OpenAM.
3) First, call auth(username, password) rest api to get the auth token. If the given credentials are okay then just send back the auth cookie to the client with HTTP 200 response code.
4) Then, you can call protected rest apis. You need to send auth cookie with your request each time.
5) Servlet filter (or something similar) checks each incoming request and validates the token. If the token is valid then the request goes forward to the rest method, if not you need to generate an http 401/403 response.
I suggest you not to write your own authentication layer, please use an existing one, for example OpenAM.
This forum topic explain everything you.

How to configure spring oauth?

I have 2 web applications:
Resource Server (#EnableResourceServer)
auth app (#EnableAuthorizationServer)
They are mapped to one database.
I would like to split database for 2: one for client app and the second one for tokens.
Question: How client app should be configured correctly with oauth?
My current flow:
Resource Server get request with token
spring security checks token in database
May be the best flow is to isolate auth app and database and flow should be something like this:
Resource Server get request token
and Resource Server makes a request to auth web app (OAuth Server) to verify token
auth app (OAuth Server) spring security checks token in database
?
Let me know if I misunderstand any point about oauth. Thanks.
If you want use the auth server for checking tokens you need a RemoteTokenServices (or the equivalent). If the server is a Spring Oauth sever (using #EnableAuthorizationServer) there should be a /check_token endpoint.
N.B. It might be a good idea to read the spec and get the terminology straight (your "client app" is a "resource server".

Categories