Make ajax call to service which using Spring loginUrlAuthenticationEntryPoint - ajax

I have a web app with spring boot that uses loginUrlAuthenticationEntryPoint and restful service next to it.The Application serves to a one web page that uses thymeleaf which authenticate using sessions and a mobile app that uses basic authentication.So there is a cart items screen (html table ) in a restaurant page , i want to make those items deleted by clicking on them asynchronously(from database).But that page's security (page url) is handled by login-url-auth-entry-point , not rest auth security config.
So when ı make a ajax call to delete cart item url it returns 302.My ajax call don't authenticate and tries to redirect me to login page. I tried many things.
I tried using xhrFields{withCredentials:true} in ajax call-didn't worked.
I tried using setting Authorization field with document.cookie - document.cookie returns empty.
There is the controller i am trying to send request:
#ResponseBody
#PreAuthorize("hasRole('RESTAURANT') OR hasRole('ADMIN')")
#GetMapping("/flushitem/{id}")
public ResponseEntity<String> freeCartItem(#PathVariable("id") Long id) {
try {
cartService.deleteCart(id);
}catch(Exception e) {
e.printStackTrace();
}
return new ResponseEntity<>(HttpStatus.OK);
}
I also tried to delete #ResponseBody annotation and make a request with thymeleaf's th:href with a html link tags.It tries to redirect to somewhere even if my controller returns void.
So long story short, my question is , how should i make a ajax call in a web page which makes authentication by sessions ? Or can i make the functionality that i want without using ajax and rest controller function ?
Im not triying to make any cors related operation.(I guess)

Related

Is it possible to protect Get Requests in Spring Boot MVC with Recaptcha (inside the Spring Boot Application)

Let's say when you send a request to this url: ...?query=something&filter=another_thing, I am returning a web page with model attribute let's say model.addAttribute('result', resultList) then just for loop the result and print the values. (Template resolver could be jsp or thymeleaf, but there is no option to load resultList without model fashion - I mean there is no ajax request - )
What I want to do:
before loading the result (or loading the page), I just want to load google recaptcha.js first and
recaptcha will return a token,
then I will send token to the backend via ajax request.
After all if request is not bot, I will print the resultList
Is this requirement possible to implement inside the Spring boot application itself?
NOTE: I could not find anyway to do this. I just though that I could intercept the original get url then redirect to the another page, and this page will load recaptcha and send the token to my backend. If it is not bot then redirect to the original get url. However I do not know how to preserve original request
You're framing it slightly wrong, which may make all the difference.
When making a request, you want to make sure that request is authorized, before you handle
it.
That is where a recaptcha comes in.
To prevent unauthorized access, look into spring-security and recaptcha for that.
Once sufficient authentication has been achieved, your request will then enter your controller, and you can serve the page.
(of course, you could look into it doing it dynamically, but that will be a bit harder)

How to read ASP.NET_SessionId in Web API Controllers?

We have a legacy ASP.NET WebForms project that I am trying to modernize by using Web APIs instead of the traditional [WebMethod] statics on Code-Behind (because it is just so limited).
However, I wanted to be able to read the Session Cookie in the Web API as well. Before, I can read it in the Code-Behind by accessing the HttpContext.Current.Session["NAME_OF_COOKIE_HERE"] and then casting it to a Model - I don't know how to do this with Web APIs.
I'm using axios to talk to my Web API Controllers.
I've added the withCredentials: true to my axios config but how do I move forward from there? How exactly can you read the session cookie in Web API Controllers?
Here's a sample:
// Client for testing
axios.get(API_ENDPOINT_URL_HERE, {withCredentials: true}).then(res => res).catch(err => err);
// Web API Controller
[Route(API_ENDPOINT_URL_ACCESSIBLE_BY_THE_CLIENT_TESTING)]
[HttpGet]
public IHttpActionResult SOME_FUNCTION_NAME() {
var currentUser = // I don't know what to do from here on.
}
The answer is in this link: ASP.NET Web API session or something?
Specifically, adding the following in the Global.asax.cs
public override void Init()
{
this.PostAuthenticateRequest += MvcApplication_PostAuthenticateRequest;
base.Init();
}
void MvcApplication_PostAuthenticateRequest(object sender, EventArgs e)
{
System.Web.HttpContext.Current.SetSessionStateBehavior(
SessionStateBehavior.Required);
}
You can read cookie just like any header property in httpRequestMessage by HttpRequestMessage.Headers .Please follow the link with proper implementation
WebAPI: Getting Headers, QueryString and Cookie Values
Also please note that if you expect a cookie in the Request then use "Cookie" header key and if you are making an rest api call and trying to find cookie in response then use "Set-Cookie"

How to use Restcall with Spring Security

In my Spring MVC application I am using spring security. It works fine so far, but I have to admit, I do not understand all the details.
In the same application the user can call some controller functions by rest api. When the user (lets say Tom) does this, his authentication is lost. Instead the controller is called by user anonymous.
I tracked down that "user switch" to the code below. Variable restCall contains an url to my application. That call would work for user Tom, if he would place it in the browser directly. Using the restcall, the user changes to anyonymous.
1) Can I prevent that, when the calling User (Tom) was already logged in?
2) As those services should be called by a user that is not already browsing the web interface of the application, I would have to find a way to login by the rest call itself.
private void callWebservice(HttpServletRequest req, String restCall) {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response
= restTemplate.getForEntity(restCall, String.class);
logger.debug(response.toString());
//assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));
}
You need, for example, a JSON Web Token (JWT) Authentication.
Steps are the following:
1) Client does an authentication, a post request with username and password
2) If authentication is successful, server returns a token in which is coded the user
3) In your next call, GET or POST, you add JWT to your header, this way the server will know who you are, because server can decode the token, and can grant also the right authorities and functionalities

Spring Security 3 - Ajax logout

I'm building a single-page web application with integrated login/logout features. The back-end is powered by Grails 3 and Spring Security 3.0.3.
From Spring Securiy doc:
LoginController has JSON-generating methods ajaxSuccess(), ajaxDenied(), and authfail() that generate JSON that the login Javascript code can use to appropriately display success or error messages.
Ajax requests are identified by default by the X-Requested-With request header.
What about Ajax logout functionality though? As far as I could understand there's no built-in support to do that, so I'm looking for advice about the easiest way to achieve this.
At the moment, with the default Spring Security configuration, the logout works as expected (i.e. users are able to logout successfully), but of course what I get from the back-end is the login page's HTML.
Thanks in advance!
Just ran into the same problem myself.
Didn't find a way to skip the redirect but by adding my own logout controller, I could at least provide an json response instead of the login page.
Add this to application.groovy
grails.plugin.springsecurity.logout.afterLogoutUrl="/ajaxLogout"
And this is my controller
#Secured('permitAll')
class AjaxLogoutController {
def index() {
def data = [:]
data.success = true
render data as JSON
}
}
There's a whole section on Ajax in the docs.

ASP.NET MVC - Failed to load resource in Response.Redirect

I noticed if my session expired whilst on my site and then I clicked on an Ajax.ActionLink, the login page would be displayed in a PartialView. I've created an override of the OnActionExecuting method like so:
protected override void OnActionExecuting(ActionExecutingContext ctx)
{
if (!ctx.HttpContext.User.Identity.IsAuthenticated)
{
if (ctx.RequestContext.HttpContext.Request.IsAjaxRequest())
{
//ctx.RequestContext.HttpContext.Response.RedirectToRoute(new { controller = "Account", action = "LogOn" });
ctx.RequestContext.HttpContext.Response.Redirect(Url.RouteUrl(new { controller = "Account", action = "LogOn" }));
}
}
}
This checks if the User is Authenticated and then if the request is an AjaxRequest. It will then redirect the user to the LogOn method in my Account controller if they're no longer authenticated for an Ajax actionlink. The problem is I get "Failed to load resource" in the console.
This checks if the User is Authenticated and then if the request is an
AjaxRequest. It will then redirect the user to the LogOn method in my
Account controller if they're no longer authenticated for an Ajax
actionlink
Yes, but if you configured your Ajax.ActionLink or Ajax.BeginForm to update some DOM element with the results of the AJAX request using the AjaxOptions, it doesn't really matter if you are redirecting on the server. The AJAX request will simply follow the redirect and insert the resulting HTML you redirected to (/Account/LogOn) inside the DOM element.
So redirecting from an AJAX request won't solve your problem. As you know the whole point of an AJAX request is to stay on the same page (the address bar never changes).
If you wanted to handle the authentication cookie expired condition in a proper way within your AJAX requests you will have to perform the redirect on the client (using window.location.href). In order to achieve that you may take a look at the following blog post in which Phil Haack exposes a great technique allowing your server to send a 401 HTTP status code in this case instead of redirecting. Then on the client you could intercept this code (by subscribing to a global AJAX handler for example) and redirect to the logon page from the client.

Resources