Authentication with google account for native desktop app with backend - java

I have an application that has both a backend and a frontend (in java). I need to have user authentication but I would prefer not to handle most of it myself. So I thought I could have users authenticate with their google accounts.
The backend part is mostly implemented, and it works fine from the browser:
I try to navigate to a URL of my server, and the browser is redirected to the google login page.
I login, and the browser is redirected back to my server, this time with auth info (some kind of token?) and I get a response.
But I'm having trouble figuring out how to set this up from a desktop app. I would like for the app to have a login button that when pressed, opens the google login page in the system browser for the user to login. If the login is successful, the desktop client can use the info from their google account (e.g. the email address) to identify itself with my server.
It's the first time I'm working on something like this, so I don't know if I'm looking in the right place. My research online leads me to OAuth2.0, but that seems more like authorization than authentication.
I looked at google's OpenID guide and it directed me to using OAuth2 for installed applications, is that the right solution for my use case? Or is that for applications that only have a frontend and all data is kept in the desktop app?

I am not completely sure whether it is secure, and whether it aligns with best practices, but I found a solution. I used the idea of the loopback redirect uri in my own way.
I start an http listener on the desktop app on a random available port, let's say it's port 54321.
I want to contact a url to my server. In that url I add the loopback port as a query argument. So the url would be something like https://myserver.org:8443/signin?loopback_port=54321
I start the system browser with this url. The server requires authentication, so the browser is redirected to google to login and provide authorization for the application to access my google account data.
Once the login in google is done, the browser is redirected back to the url of my server that it was first trying to reach. Now since the authentication is done, the request goes through.
I updated the /signin endpoint on my server to return redirects to /signin2 (again with the loopback_port param). The redirect from /signin will set the JSESSIONID in a cookie in the browser, and when we get the request in /signin2, we can read that JSESSIONID.
When we get the request in /signin2, we use the loopback port and the jsessionid to build a redirect url to the http listener on the desktop app. The jsessionid will be included as a query argument. So the browser is redirected to http://localhost:54321/?JSESSIONID=....
The http listener on the desktop app parses the request to get the JSESSIONID from the cookie, and it can use that in subsequent requests it sends to the server. Having this cookie, the server associates the desktop app's request with the authentication done earlier.

Related

Allow browser to connect on HTTP website - Playwright Java

Currently, I am testing an application that has a sign-in form and after successful authorization, sign-in should redirect the user to a custom URL that contains a code, for now, that URL is localhost. After redirect on GUI less, I see that redirect link on chromium, and second, after redirect, I get this kind of error:
chrome-error://chromewebdata/
Basically, it says that chrome could not connect to that specific URL. is there an option to allow Playwright to connect on redirected localhost URL? Without any proxy or some kind of other things that are being used. So far I haven't found any helpful information about this topic when the user gets redirected to an HTTP page instead of HTTPS.
I hope that there is a solution to my issue.

Is it possible to post login form to an external web app and also redirect to that app's front page?

I have a web application that when user click on the a link it will generate security information and log on to an external application if the security information is authenticated.
At this point from security concern I don't want to expose the URL and request information on the web page, so instead I am seeking solutions to handle the process behind the scene
I know Apache Components can easily send post request within POJO, jersey client can do as well through web service. However the requirement here is also including to let browser automatically redirect to the 3rd app's front page if the login process succeeded.
My question is what could be the proper solution to handle the login process and go to the external application from web as well.
Say you have:
publicapp.com
secretapp.com
Set up an API in publicapp.com to POST the initial request to itself. When the user submits the initial login form it goes to say publicapp.com/login. This endpoint will pre-process the information then send a server to server request to secretapp.com/login.
If secretapp.com/login accepts the information it responds to publicapp.com with a success and publicapp.com redirects the client to secretapp.com/home, with a short term auth token encoded in a JWT. secretapp.com, swaps the short term token for a full auth token.
In the above scenario, the actual login endpoint is never made public. secretapp.com should also have IP whitelisting to only accepts login attempts from publicapp.com. You can also do a lot of filtering on publicapp.com to eliminate malicious requests without bothering secretapp.com.

How to implement Java soap client when server uses ADFS authentication?

We are implementing a soap client in Java (using cxf wsdl2java). In previous projects the authentication has been based on either WS-Security or Basic HTTP Authentication. These are both easy to test in SoapUI and implement in java.
This time however, the server uses a Web Application Proxy which works as a reverse proxy, and ADFS (Active Directory Federation Services) for authentication purpose. I don't know the details of what this means, but what happens when opening the wsdl endpoint URL in a browser is that we get redirected to a login page similar to the office login page https://login.microsoftonline.com/ where you have manually click on the account type before entering credentials.
When logging in manually, we get redirected back to the wsdl endpoint with an appended ?authToken=xxx at the end and I think the token lasts for 1 hour. We have tried to ask the provider to use a more standard authentication, but for now this is the only thing we have. How do we approach this?
When trying to do a test request from SoapUI, we just get the complete html code of the login page in response. I see there is a Form Based Authentication option in SoapUI but it won't work since the login page has multiple account types and multiple username/password fields. The workaround for testing is just to login manually and use the authToken. But how can we automate this in the Java cxf client?
When connecting to the endpoint url in a browser, this is how the url looks after redirected to the login page:
[url to adfs seriver]/adfs/ls?version=1.0&action=signin&realm=urn%3AAppProxy%3Acom&appRealm=a10037ed-ca1e-e711-9436-00215a9b01ac&returnUrl=[wsdl endpoint url]&client-request-id=13A5B5A6-B574-0000-6FBA-A51374B5D201
You can't use SOAP to authenticate with ADFS via a login screen. This is because ADFS only supports WS-Fed or SAML-P or OpenID Connect (ADFS 4.0).
What you can do is use WS-Tust to do this.
WS-Fed supports two profile viz. passive (browser login screen) or active (web service / WCF). You need to use the latter.
There are a number of active profile endpoints that are available in ADFS. Not all are enabled by default so you may need to enable them.

How to prevent login prompt for guest users via Integrated Windows Authentication?

I have Tomcat application and I want to add support for Integrated Windows Authentication (IWA). I want to the following behavior:
If user is domain authenticated user - I want to get user name from request (IWA itself)
If user is not domain authenticated user - I just want to show my custom page with form to login and authenticate it manually.
So, my application has the following workflow:
user loads static AngularJS page
This page makes AJAX request to the URL like /login/check_iwa
Server side for /login/check_iwa sends 401 WWW-Authenticate: Negotiate
if the user is a domain user - then the browser will resend the request with the user's credentials, if not - nothing happens, JS gets 401 and understands that the user is a guest.
And I have problem at step 4. IE and Chrome always show login prompt (with FF there is no login prompt) for guest users.
Is there a way to avoid login prompt? I have my own beautiful form for login, I don't want native login prompt for guest user.
It seems, that I need only Kerberos authentication, but IE and Chrome use NTLM authentication with login prompt.
Do I need to send 401 WWW-Authenticate: Kerberos instead of Negotiate?
The popup dialog in IE is hardcoded, you won't get it away. It is querying for alternative credentials which are passed to SSPI. Switching to Kerberos instead of Negotaite will give you nothing because no browser (IE, Chrome, FF) support Kerberos directly but through SPNEGO only. You are out of luck. You are probably better off with Basic if SPNEGO fails but at the end, failing Kerberos in an enterprise environment simply means that your network setup is faulty and needs to be fixed.
Edit: Since you want to serve intranet and Internet users, you need a sifting authenticator. If you happen to use an Authenticator on Tomcat side, you could easily write a SiftingAuthenticator which decides based on the range of IP addresses what succinct authenticator is best. Use the CombinedRealm as template.

Continuing sessions using JSESSIONID

I have a web application which requires username and password authentication to enter.
What I am doing is, authenticate a user from a stand alone Java app, which would do so by making Http request to the server using username and password. Then I would retrieve JSESSIONID cookie from response of server.
Now what I want is to use this JSESSIONID to continue session on browser i.e. to let user navigate pages of my web app which would be opened by my stand alone java app which I use for authentication.
Is this possible? Or is there any other way to do so.
Cookie can be changed using below mentioned methods.
Cookie cookie = new Cookie("JSESSIONID", NEWSESSIONID);
response.addCookie(cookie);
From your application you can send JSESSIONID as parameter while opening browser first time and reset your cookie using above method either in filter or servlet. This will reset your cookie in client side once you send response back. Next request on wards you will be able to access the session created previously.
It's possible but it's not that simple.
Since web applications don't share sessions, what you're looking for is a Single Sign On (SSO) solution, which involves an "Identity Provider" (IdM) that authenticates users for one or more "Service Providers" (SP). In this case, your servlet is the IdM and your web app is an SP.
Depending on your deployment, the following are third-party, open-source SSO libraries that you may be able to use:
Kerberos
PicketLink (for JBOSS)
OpenAM (for Tomcat)
If you don't want to use a third-party library, you may also be able to modify your servlet to be the IdM. Either way, I suggest reading a little about Security Assertion Markup Language (SAML) before deciding on a solution. SAML is a popular method that the above libraries implement.

Categories

Resources