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

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.

Related

Authentication with google account for native desktop app with backend

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.

How to authenticate and authorize Java application with KeyCloak

I have a Java servlet that accepts HTTP requests, "protected" by KeyCloak. I can manually send a GET request, which redirects me to the KeyCloak login page, and I can log in and see the correct webpage from the servlet. Now I would like to make it such that my other Java application can also authenticate itself and access the webpage.
In my current setup I have the Java servlet running in Wildfly and the keycloak standalone. I have a KeyCloak realm with a user "testuser" with the role "testrole" and client "testclient". To be fair I don't really know what the client does, since it has no role or other attributes set. Should it represent the servlet application or the requesting Java application? What attributes should I set here?
The documentation mentiones JWT Tokens, but I don't know how I can obtain one. The actual request should be to "localhost:8080/testservlet" , do I have to query for a token at the KeyCloak server first, or should I go through the redirect process as when it is "manual"?

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.

Disable redirect to last accessed resource on form login Glassfish

I'm going to rewrite my previous question.
Glassfish redirects after form login to the last accessed resource, how do I go about to turn this off?
Our problem is that we get 415 in FF and IE because if I have a JSESSION cookie Glassfish will redirect to the last resource I tried to access but does not switch content type from (x-form-urlencoded).
Pseudo example (requests are the browsers' XMLHttpRequest):
GET /secure/resouce1 (json) -> Response "you're not logged in."
GET /login.xhtml
POST /j_secure (x-form-urlencoded) -> New location /secure/resource1 (x-form-urlencoded)
GET /secure/resource1 (x-form-urlencoded) <- HTTP ERROR 415 content type not JSON.
You will probably need to write a Filter to check for and catch that case. I like this tutorial (hoping the translation to English is understandable).
In my opinion it is better to use Basic or Digest authentication over SSL for RESTful services. Other options are including the credentials as part of the payload or creating a dedicated login service, which accepts credentials and returns a token. There are various reasons why form based authentication is less suitable for RESTful service: it requires a session, it does not use the existing HTTP Authorization and more.
If you need to call your RESTful service using AJAX then using a cookie for authentication can be a valid solution. They should only affect if the user can make a call, but not how the server responds.
If you would like to keep using form based authentication for your application I would suggest adding an additional JAAS authentication provider which will handle the RESTful services authentication. You can read more about it here.
Another option, which should be easier than JAAS, would be using Spring Security or Apache Shiro instead of the container based authentication.
Here is an example of configuring form based authentication with Spring Security. This post shows an example of how to secure RESTful services using Spring Security.
in your login page
reset the JSESSIONID cookie to prevent redirect last page
// login_form.jsp
Cookie jsess = new Cookie("JSESSIONID", null);
jsess.setMaxAge(0);
jsess.setPath(pageContext.getServletContext().getContextPath());
response.addCookie(jsess);

HTML5 mobile app security

I'm developing a html5+jquery+phonegap application. Server side is written in java and Spring MVC.And I hope to implement an authentication model as follows.
client signs up using his email which would be used as his userID.
A token is sent to his email.
He is given a screen to enter the token.
That token is stored in the local storage of the client.
everytime the client calls a webservice, his userID and token is sent by the app over https.
Server authenticates him and responds.
What are the options available to implment this kind of security from the server side? can Spring-security be used in this way? I tried to find any implmentation with Spring-security, but couldn't find any implmentation other than basic authentication.
You can use PreAuthenticationProcessingFilter to achieve this requirement, have a look similar case and spring security doc

Categories

Resources