Spring, XSRF tokens and performance - spring

I am trying to implement CSRF protection in an existing application. We have Spring MVC on backend and a mix of HTML, CSS and Apache Velocity Templates on frontend.
I have tried configuring the Spring CSRF functionality as shown here - https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html. After reading through this Spring documentation, I get a feel that after configuration, Spring Security would automatically send tokens with all requests but that is not happening in my case - perhaps something is wrong with my configuration.
As an alternative, I am creating an instance of Spring Security's CsrfTokenRepository and calling generateToken and loadToken methods on it in my front controller which intercepts all HTTP requests coming to the server. This way, I am able to deliver a new token for every HTTP request and then send it back on the next one.
The mechanism fails though if I click different links within my page too frequently - by the time a page is rendered and the new token is set in hidden fields, the browser has already sent a request to another page with an old token. It also fails when I open more than one tab since the token received by the latest opened tab wins over tokens from tabs opened before it.
To overcome this issue, I changed the tokens to be generated only per session. However, now I run the risk of tokens being exposed - via get requests or referrer fields for example. Is there a way to improve the performance of per request tokens? or make the approach more secure with per session tokens?

Related

Dynamically Update Page in Application Requiring Authentication Via Azure AD

I am curious if anyone has a solution to this unique situation as I have a solution currently, though I feel it is not the most optimal.
The Situation.
I have built an MVC style web application that talks to a web API through http (authenticating via JWT). My web application is secured by appending authorization to its view controllers and redirecting to a Microsoft login endpoint - then directing back to the view where whichever given controller/function handles the request, connects to the API, appends data to the view, etc.
Preferably I would like to use JQuery/Ajax to submit http requests client-side and update a given view with whatever data the user may wish to see relative to the webpage they're on. This way I could control exactly what the user should see landing on the page any which way and submitting requests from web app to API. Also would enable better continuity between requests as there isn't actually a full refresh of the view. All in all it is my line of thought that this execution would lead to a nice user experience.
The Problem.
So the big issue that I have had to circumvent is CORS Policy. I initially attempted to use JS just as I said above but requests would be redirected to the login endpoint and blocked due to there being no CORS header appended to the request.
'So include a policy in your application and append an authorized header to your Ajax outgoing request' you might say, well... you cannot override CORS security around Microsoft's login endpoint.
My Solution.
What I have done simply instead is create HTML Forms around fields the user would pick and chose to specify what data they wanted from the API. Then carry over input data to the returned view via 'ViewData'
and using razor pages of course I can actually initialize JS variables via C# input.
Side Note
I use JS to transform the API data into graphs for the user to see. I am doing this with a JavaScript Library.
My Question to you.
This all leads me to ask then, is there a way to dynamically update a view without using JS? I require a method that can hit the login redirect without being blocked because the request initiated client-side.
Every solution I am aware in some way, shape, or form utilizes JS to make the request. So I am at a loss for how to truly get the functionality I am after without having my requests get blocked due to CORS Policy.
Thanks in advance y'all.

Can't understand how to work with OpenID protocol using openidConnectClient-1.0 feature and Angular application which using REST API endpoints

So, I have a WAS Liberty server which configured to work with OpenID provider. Then I have an Angular application which heavily using REST Api endpoint.
When I first open an application or open it after token has been expired everything is ok, WAS redirects me to OpenID provider and then regular flow defined by OpenID and backed by openidConnectClient-1.0 implementation.
But how do I suppose to care about following use case: token has been expired while the application were open, and user issues GET or POST request without reloading the application? Right now WAS perform redirect too, so I can't actually distinguish between regular response and redirect (both return status 200).
The only solution which I think about is to say to Websphere not to perform redirect for some endpoints but to return 401/403 errors. So I'll be able to monitor response codes in my client side and perform accordingly. Is it possible to achieve? Perhaps there's another solution which I didn't know about?
Update: After I've written this I thought about using Authentication Filters, i.e. define something like:
<authFilter id="testFilter">
<webApp id="simple" matchType="contains" name="simple"/>
<requestUrl id="excludeUrl1" matchType="notContain" urlPattern="/basic"/>
<requestUrl id="excludeUrl1" matchType="notContain" urlPattern="/api"/>
</authFilter>
But I immediately see two drawbacks on this approach:
Maintain app's logic in two different places, server.xml and app itself. It'll make maintenance of the application very cumbersome.
Due to nature of Authentication Filters it will fallback to another registry to perform login. It potentially can be a security flaw.
Update 2: Solution from above doesn't work. When server returns 401 Error together with www-authenticate header, browser shows popup of basic authentication, see proposed solution below.
To resolve this issue I've used Angular's Interceptors, where I check if there're following headers within the response: no-cache, no-store, must-revalidate, private, max-age=0. If they persist within the response I know that session expired and perform reloading of my application.
While reloading, liberty itself redirect it to SSO provider. Another solution is to extract redirect URL from response and redirect to it manually.

Spring Security - REST API - token vs. cookie

I have written a REST- API in Java and I have secured this API with Spring Security. The procedure is like this:
Frontend invokes /login RestService in Backend
Backend gives back token to frontend
at each REST- API Backend invokation the token has to be placed in header
This works fine, but I have read that it is also possible (with Node.JS/Passport.js/Express.js) that the session object with the cookie inside can be transfered out of the box without any custom code.
My question now would be if there is a better approach so that the frontend/client do not need to set the token into the header all the time for any request.
Usually token based authentication has advantages over cookie based.
You can achieve this using middle-ware layer
Here is a good Post - https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/
Server side, I usually first check in the headers if there is an auth token. If not, I then check in the cookies as a fallback.
If you want to use cookies, then at your step 2, you need to add a Set-Cookie header to the response, so that browsers know they must store a cookie. Once done, no need to add a header client-side, since browsers will send cookies each request. You'll need to add a CSRF protection though (here is a good example).

Securing jQuery calls to Spring MVC REST API using Spring Security

I'm developing a REST JSON API with the Spring MVC Framework. I want to serve a single HTML application to the user and the whole communication between server and client is done with JSON format. So the client single HTML application uses jQuery to send AJAX calls to the server.
My big problem is to find the right way to do integrate a proper security technique. I read a lot about basic, digest or form based authentication via Spring Security, but I don't think this is the right way. I want to get JSON responses if the user isn't logged in and I don't want to send a jsessionid with each request.
Could you please tell me the right way or the best-practice how to authenticate user by performing AJAX requests? Maybe it's OAuth 2-legged? (don't have much clue of OAuth)
If you don't want to store auth information in server-side session (and use JSESSIONID in cookies/urls) you may send auth info with every ajax request using BASIC auth header (created in JS).
I've never used 2-legged oauth, so I won't comment about it.
edit: typo

How to design authentication and authorization system for REST backend / Ajax front End Application

I am starting a new project where we are planing to build a restful back end and an AJAX font end. I am approaching the problem by focusing on Identifying all the resources that I have and what the various HTTP verbs will do them, their URI and the JSON representations of those resources.
I am looking for the best design for securing the backend. Here is the list of designs I have considered. I am looking for alternative designs not listed below, and pros, cons recommendations. The system will be implemented with Spring 3.0 and possibly Spring Security 3.0, SSL will be used for many parts of the system but not for all of them, so some requests may come on SSL and some might not.
Option 1: Use the HTTP session
Show a standard login screen, create a server side session and let tomcat send back a jsessionid cookie and have the ajax client include the JSESSIONID cookie on every XHR request. This options just feels like it's the wrong approach for the following reasons.
The connection becomes statefull which is against the rules of REST
I want to be able to split the bakcend into multiple seperate WAR files which means i could have multiple HTTP sessions on the backend, if that is the case then this approach does not work. While I don't need the ability to split the backend into multiple apps today, I would prefer a design that allows for that possibility.
Option 2: Find an open source Java based security library that does this
Other than Spring security I have not found any other Java libraries, any recommendations are highly appreciated.
Option 3: Try to use an existing protocol like OAuth
In my very brief look at OAuth it seems that it is designed for authentication across sites where each site has it's own user database. In this system i want a global user database shared across all the backend ajax services.
Option 4: Use SAML and Shiboleth
This options seems over kill and hugely complex to setup and maintain.
Option 5: Send the username and password with every request
This requires that user sends their username and password with every request, which means that the front end AJAX app must store the username and password as a JavaScript object and if the user navigates away from the page then back the username/password combo will be gone and the user might be forced to log in again. I don't want the front end to try and put the username and password into cookie as that would comprise security.
Option 6: Implement my own authentication / Authorization protocol
Create a REST service that users can present their username/password combination to and then get back and security token, which they must send back to the service with every request. The security token would be digitally signed by the service and would have an expiry time. The token would be only good for most operations high security operations would require a new login screen as port of confirming the operation.
Problem with this approach is I have to invent yet another security protocol which seems like a total waste of time.
I am sure I am not the only person up against this problem, I hope the stack overflow community can point to some options and tools that I have not found yet.
Take a look at Apache Shiro. It is an authentication system that has a session management feature that can be used to share sessions across applications. This may be the easiest thing to do.
Or you could use Spring Security (or Shiro) with a Remember Me cookie that is shared across the webapps (as long as they are in the same HTTP domain). The remember me cookie would be analogous to your token in option 6. You can set the expiration on the cookie that so it is short lived like a session cookie or long lived like a regular remember me.
You might also want to take a look at Jasig CAS - Single Sign-On for the Web. It has a REST API and a protocol (Proxy Tickets) that allows services to proxy user AuthN to backend services like you described in option 6. http://www.jasig.org/cas
Briefly...the application that serves up the AJAX client is protected with Spring Security (supports CAS out of the box) and gets a Proxy Granting Ticket that you embed in the AJAX client. The AJAX client uses the PGT to get Proxy Tickets for your REST services...protected with Spring Security too. The REST services get an authenticated userId without every touching primary credentials.
Alternative, you could keep the PGT on the server and use AJAX calls to retrieve Proxy Tickets that are then used by the AJAX client to call you REST services.
As I understood you are going to secure a rest application, to preface you must know that a security provider consisd of three concepts (3A):
-Authentication
-Authorization
-Auditing
to implement these three together you must provide bunch of tools such as :
-SSO provider
-Session Store
-Open Id pattern
-user credentials integration
....
I have used ACL(Spring ACL) to provide authorization services and oauth2 for authentication.
there is one channel to connect these two together and its scopes(oauth2 scopes) but the problem is scopes are not flexible(pure strings) enough to implement authorization modules such as role_voter, cache_strategy, black_list or,Role_base strategy, exceptional permissions, white_list... (but you can use #EnableGlobalMethodSecurity)
In my case I used authorization server as a resource for oauth2 authentication server(take a look at http://projects.spring.io/spring-security-oauth/docs/oauth2.html), then I considered two spots to check authorization, the first I issued ACL to front-end and forced programmer to design her page dynamically up to ACL concept, the second is in back-end on service layer(BLL) using Aspect when one rest is going to be called. I sent the service key as an actee to check if current user has enough access control to do that. and for auditing you must monitor all requests I mean you must use an listener in your gateway or broker...

Resources