Spring security - login page and j_spring_security_check post method

Hi all,

I use spring security with my vaadin’s application and I have problem with my login page. First I used simple login page which was write in jsp and works fine. Now I would like to use login page which will be write as vaadin app. I made another servlet 'Test’which is avaliable with ANNONYMOUS_ROLE

	<servlet>
		<servlet-name>Test</servlet-name>
		<servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class>
		<init-param> 
			<!-- Define our application class for servlet. -->
			<param-name>application</param-name>
	    	<param-value>com.login.LoginApp</param-value>
		</init-param>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>Test</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>  

My main servlet:

	<servlet>
		<servlet-name>VaadinSpringServlet</servlet-name>
		<servlet-class>pl.polsl.aei.dovecote.server.spring.SpringApplicationServlet</servlet-class>
		<init-param>
			<param-name>applicationBean</param-name>
			<param-value>applicationBean</param-value>
		</init-param>
	</servlet>

	<servlet-mapping>
		<servlet-name>VaadinSpringServlet</servlet-name>
		<url-pattern>/test/*</url-pattern>
	</servlet-mapping>

My security xml:

	<sec:http auto-config="true" access-denied-page="/login_error.jsp">
 		<sec:intercept-url pattern="/" access="ROLE_ANONYMOUS" />    
  		<sec:intercept-url pattern="/jsp/login_error*" access="ROLE_ANONYMOUS" />  
  		<sec:intercept-url pattern="/test/**" access="ROLE_USER" />  
 	 	<sec:form-login login-processing-url="/j_spring_security_check" login-page="/" authentication-failure-url="/jsp/login_error" /> 
	</sec:http>

When I go to page http://myapp/ I am redirect to ‘Test’ servlet and my login page appears. Now I try to make j_spring_security_check’s post request but I don’t know how can I do it. I try use RequestBuilder from GWT but it doesn’t work (I get UnsatisfiedLink error when a use URL.encode…)

Can someone help, any suggestion?

Where are you trying to build the request - in a custom client side widget?

The widgetset (JavaScript part running in a browser) of a Vaadin communicates with the server using asynchronous XmlHttpRequests, with a custom protocol, and does not e.g. do such HTTP POST requests that Spring Security expects. The bulk of your application is running on the server, and you cannot use e.g. GWT RequestBuilder there.

You need to either send the authentication request from custom client side code (the
FormSender
add-on might or might not help, with an extra round-trip to the server) or skip the Spring Security AuthenticationProcessingFilter (org.springsource.security.web.authentication.UsernamePasswordAuthenticationFilter that is automatically put in the servlet filter stack by <sec:form-login …/>) and instead perform the authentication in the Vaadin login application.

The latter approach would in some ways be the “clean” one (not trying to shoehorn Vaadin to the JSP model, nor pass authentication data back and forth between the client and the server). It fits better the Spring Security architecture, but does require a bit of coding and testing.

Some completely untested pseudo-code based on Spring Security AbstractAuthenticationProcessingFilter and UsernamePasswordAuthenticationFilter:


// method called by the Vaadin login application "Login" button click listener
protected void performLogin(String username, String password) {
    if (username == null) username = "";
    if (password == null) password = "";
    username = username.trim();

    UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);

    authRequest.setDetails(new WebAuthenticationDetails(request))

    Authentication authResult;
    try {
        authResult = getAuthenticationManager().authenticate(authRequest);
    } catch (AuthenticationException failed) {
        unsuccessfulAuthentication(request, response, failed);
        return;
    }
    successfulAuthentication(request, response, chain, authResult);
}

protected void successfulAuthentication(...) {
    SecurityContextHolder.getContext().setAuthentication(authResult);

    // optionally getRememberMeServices().loginSuccess(request, response, authResult);
    // optionally getEventPublisher().publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
    // optionally getSuccessHandler().onAuthenticationSuccess(request, response, authResult);

    // TODO redirect to the correct application URL
}

protected void unsuccessfulAuthentication(...) {
    // optionally getRememberMeServices().loginFail(request, response);
    // optionally getFailureHandler().onAuthenticationFailure(request, response, failed);
}

Then redirect to the main application on successful authentication. The method getAuthenticationManager() should get the AuthenticationManager bean from the Spring context, where it is put by your auto-configuration.

You could also replace the ExceptionTranslationFilter in the servlet filter stack, but that might not be necessary as the default implementation redirects to an authentication page if I remember correctly.

Feedback on if you get this working and ideally an add-on in the directory for doing this cleanly would be nice.

Thanks you for your comprehensive answer. Yes, I tried build the request in a custom client side widget.
Of course, I will write feedback, but not until late in the evening.
Thanks one more time for your reply!

Hi,

Yesterday I tried use FormSender but I lost battle, also with the second idea.Lack of time I leave the login panel as a jsp page. If I will have more time to come back to the problem, I will try to resolve it and describe here. Unless someone do it before me :slight_smile:

@Henri Sara: anyway thank for your help

Hi jan polok,

if u find some way to use vaadin login page instead of jsp login page, please let me know the procedure . i am also trying to make it …but not getting succeed.

thanks.

Unfortunately I couldn’t do that :confused: