Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Login with Spring security using Ajax

I am trying to work on Ajax based login system using Spring Security and it was working fine, till I got with another requirement where I need to configure authentication-success-handler, so as I can do some post processing once user is authenticated by Spring security.

Earlier I was not using <form-login/> for showing Login page.My Login section is a drop down and part of header section which is common for entire application.

This is how I am trying to configure Spring security

<http pattern="/customer/**" auto-config="true" use-expressions="true" authentication-manager-ref="customerAuthenticationManager">
<!--<http pattern="/customer/**" auto-config="true" use-expressions="true">-->
<intercept-url pattern="/customer/logon.html*" access="permitAll" />
<intercept-url pattern="/customer/denied.html" access="permitAll"/>
<intercept-url pattern="/customer" access="hasRole('AUTH_CUSTOMER')" />
<intercept-url pattern="/customer/" access="hasRole('AUTH_CUSTOMER')" />
<intercept-url pattern="/customer/*.html" access="hasRole('AUTH_CUSTOMER')" />
<intercept-url pattern="/customer/*/*.html" access="hasRole('AUTH_CUSTOMER')" />

<form-login login-processing-url="/customer/logon.html" login-page="/shop/home.html" 
authentication-success-handler-ref="webshopAuthenticationSuccessHandler" />

<logout invalidate-session="true" 
   logout-success-url="/customer/home.html" 
    logout-url="/customer/j_spring_security_logout" />
 <access-denied-handler error-page="/customer/denied.html"/>
    </http>

With these configuration, when ever I am clicking on login button with correct credentials, i am getting HTTP 302 error

http://localhost:8080/shop/customer/logon.html 302 found

Not sure what exactly I am doing wrong?

<form id="login" method="post" accept-charset="UTF-8">
    <input id="userName" type="text" name="userName" size="30" />
    <button type="submit" class="btn">Login</button>
</form>

Ajax Code

 var data = $(this).serializeObject();
  $.ajax({
  'type': 'POST',
  'url': "<c:url value="/customer/logon.html"/>",
   'contentType': 'application/json',
    'data': JSON.stringify(data),
     'dataType': 'json',
....
}}:

Login Section

 Authentication authenticationToken = new UsernamePasswordAuthenticationToken(customer.getUserName(), customer.getPassword());
   try {
       Authentication authentication = customerAuthenticationManager.authenticate(authenticationToken);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        resp.setStatus(AjaxResponse.RESPONSE_STATUS_SUCCESS);
           } catch (AuthenticationException ex) {

            resp.setStatus(AjaxResponse.RESPONSE_STATUS_FAIURE);
   }

Any inputs? With all my efforts, I am still getting 302 and with above configuration, even my logon.html controller is not getting called.

My main issue is when I am enabling Spring security using

<form-login login-processing-url="/customer/logon.html" login-page="/shop/home.html" 
    authentication-success-handler-ref="webshopAuthenticationSuccessHandler" />

I am getting 302 from logon.html and even logon.html Controller is not being triggered (placed debugger on it)

like image 870
Umesh Awasthi Avatar asked Dec 12 '13 08:12

Umesh Awasthi


People also ask

How to secure the login page in spring?

The first feature was fairly easy to implement thanks to Spring Security. Its configuration supports a requires-channel attribute that can be used for this. I used this to force HTTPS on the "users" page and it subsequently causes the login to be secure.

How to secure login to a website using Ajax?

Implement login with Ajax, with the request coming from an insecure page. The first feature was fairly easy to implement thanks to Spring Security. Its configuration supports a requires-channel attribute that can be used for this. I used this to force HTTPS on the "users" page and it subsequently causes the login to be secure.

How to use a custom form for authentication in Spring Security?

Whenever we use a custom form for authentication in place of the one provided by Spring Security, we have to inform Spring Security of it using the formLogin () method. We then also specify our login URL – /login. We will map the URL to our custom login page in our Controller later.

How to configure Spring Security login using XML configuration?

Similarly, we can use the XML configuration: If we don't specify this, Spring Security will generate a very basic Login Form at the /login URL. 8.2. The POST URL for Login The default URL where the Spring Login will POST to trigger the authentication process is /login, which used to be /j_spring_security_check before Spring Security 4.


2 Answers

First you don't need a controller, spring security handles all this for you. So drop the controller.

The current problem is due to your JSON based post. This is handled by the normal filter which handles login, but it doesn't see a j_username and j_password field and as such will redirect (the 302) to the login page (in your case /shop/home.html) asking for those fields.

Basically you are posting the data as JSON whereas it simply should be just an ajaxified form post. This allows you to write a simple AuthenticationSuccessHandler which simply returns a 401 or a 200 status-code (and maybe a body) when things are ok.

Changing your ajax submit to something like this should make things work.

var data = $(this).serializeObject();
$.ajax({
    'type': $(this).action,
    'url': $(this).target,
    'data': data
}):

This should create a ajax form post. Might be that you need a call to preventDefault() in the surrounding method to stop the form from actual posting.

like image 192
M. Deinum Avatar answered Oct 02 '22 01:10

M. Deinum


With the login form that is currently posted it cannot work, as a form like this is needed:

<body>
  <form action="/j_spring_security_check" method="POST">
    <label for="username">User Name:</label>
    <input id="username" name="j_username" type="text"/>
    <label for="password">Password:</label>
    <input id="password" name="j_password" type="password"/>
    <input type="submit" value="Log In"/>
  </form>
</body>

The post needs to be done j_spring_security_check, and username and password need to be suplied in fields j_username and j_password, otherwise it won't work.

I think you are getting a redirect to a login page.

You can see where the redirect is going with the chrome debugger or firebug if using firefox.

To approach this first get the rest of the config working with the default login page generated by spring security, by removing login-page="/customer/logon.html".

Once this works you can add back the custom login page, but it needs to have the elements above.

Also I believe you are trying to post a JSTL tag via ajax to the server? If it's true it won't work, otherwise can you edit the question.

Try it step by step by first using the default login page, then with an ajax request with hardcoded values just for testing and then when this works with a custom login page.

like image 33
Angular University Avatar answered Oct 02 '22 01:10

Angular University