Cross-domain authentification with Spring Security - java

I have a web application built on Spring framework and running on Tomcat (lets call it exampleA.com). It has an API method for authentification - /securityLogin
And i have another site on a different domain (exampleB.com) that have an ability to send authentification request to examleA.com via API. And if the authentification is succesfull, user must be redirected to exampleA.com and be already authentificated. It all works fine by this point, session is created on the server, but user is not authentificated on examleA.com after redirect. I understand that this is because of my applications based on different domains, but i have no idea how can i fix this. Any suggestions?

OK, i have found the solution. I've just added
xhrFields: {
withCredentials: true
}
to my jQuery AJAX call, in order to allow JavaScript to pass my JSESSIONID cookie to the server

Related

How to do a logout from SiteMinder session for a Pivotal Cloud Foundry hosted JSP/Servlet application?

I am having a JSP/Servlet based application running on Pivotal Cloud Foundary and using Siteminder for authentication.
The logout we implemented but is unsuccessful currentnly includes
clearing of request.getSession().invalidate()
followed by clearing of cookiesn (request.getCookies followed by setting MaxAge of all cookies to 0)
followed by calling of the siteminder provided /logout url in new popup window
followed by window.location as PCF Logout for logout from the PCF application.
With above steps the logout is not successful. However if I do the Shift+Cntrl+Del and delete the cookies --> then the logout works successful. So programmatically I want to achieve the same behavior using Servlet and JSP.
Thanks in advance!
Using the Pivotal SSO Tile, there are two steps you need to do to make this work.
First, you need to set up your plan using the Layer7 SiteMinder Integration Guide.
As is listed there...
Single Sign‑On supports service provider-initiated authentication flow and single logout.
This is a fairly complicated process and very specific to your provider. The only tip I can give you here is to do things exactly like in the docs. It's very easy to break stuff, so following exactly what's written gives you the best chance for success.
Once you get your plan set up, the second part would be to create a service instance using the plan & bind that to your app. Then follow the instructions for integrating your app.
The part to take specific note about, which is what handles the single logout is documented in the API here.
The logout endpoint is meant to be used by applications to log the user out of the UAA session. UAA will only log a user out of the UAA session if they also hit this endpoint, and may also perform Single Logout with SAML providers if configured to do so.
If you follow the docs for creating your service plan, it will be configured to do single logout, so you just need to make sure this endpoint is called after logging a user out in your app.
There's an example of how you'd do this for Spring Boot apps here.
#Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
UriComponents url = UriComponentsBuilder.fromHttpUrl(request.getRequestURL().toString())
.replacePath("")
.build();
UriComponents redirectUrl = UriComponentsBuilder.fromHttpUrl(ssoServiceUrl)
.path("/logout.do")
.queryParam("client_id", clientId)
.queryParam("redirect", url.toString())
.build();
response.sendRedirect(redirectUrl.toString());
}
To explain, this code get's invoked by Spring after a successful logout. The code here is simply creating a URL to the /logout.do endpoint & issuing a redirect to the client. This is what's described in the doc link above.

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"?

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.

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);

Calling a REST web service secured with Spring Security from Android

I'm hosting a REST web service in a Grails application, using Spring Security, i.e.:
#Secured(['IS_AUTHENTICATED_REMEMBERED'])
def save = {
println "Save Ride REST WebMethod called"
}
I'm calling it from an Android app. (Calling the unsecured service works just fine.)
To call the service, I'm manually building up a request (HttpUriRequest) and executing it with an HttpClient.
I'm wondering what the best practices are, and how to implement them... Specifically, should I:
Perform a login once, to retrieve a JSESSION_ID, then add a header containing it into the HttpUriRequest for each subsequent request?
Or (not sure how I would even do this) include the login and password directly on each request, foregoing the cookie/server-side session
I think I can get option 1 working, but am not sure if Spring Security permits (2), if that's the way to go... Thanks!
--also, there isn't any library I'm missing that would do all this for me is there? :)
Spring security does support both basic authentication and form based authentication (embedding the username/password in the URL).
A REST service is generally authenticated on each and every request, not normally by a session. The default spring security authentication (assuming you're on 3.x) should look for basic authentication parameters or form parameters (j_username and j_password) (in the form http://you.com/rest_service?j_username=xyz&j_password=abc).
Manually tacking the j_username/j_password onto the URL, adding them as post parameters (I believe), or setting the basic authentication username/password should all work to authenticate a REST service against the default Spring Security interceptors, right out of the box.
I will admit that I haven't tried this on REST services, though I do clearly recall reading exactly this in the docs as I did the same for basic page logins on spring security recently. Disclaimer over.
I think you can use a login-once-and-get-a-token method that's similar to how oauth works.
sending username and password across the network outside of secured channel(https/ssl) is a terrible idea. anyone on the network can sniff your request package and see the clear text password.
on the other hand, if you use a token method, since the token string is randomly generated, even the token is compromised, the worst case is someone can use the token accessing your REST API.
another solution is going through ssl tunnel(HTTPS). i have actually done a comparison and result shows: 80 requests/min(https) vs 300 requests/min(http)

Categories

Resources