0

I'm creating a web app that will be run on a single page. For this reason, I need to have my authentication paths accessible using only Ajax calls (no redirection).

I'm using Spring Security and I have the login and logout functionality working fine so far. The issue is that when the user is already authenticated and they POST to the login-processing-url they are actually logged in again. What I want to happen is my jsonAuthenticationHandler or some other handler to return a 500 or something telling me I can't log in again.

Here's what I've got for my security XML:

<sec:http use-expressions="true" entry-point-ref="jsonAuthenticationHandler">
    <sec:intercept-url pattern="/data/**" access="isAuthenticated()"/>
    <sec:intercept-url pattern="/data/login" access="!isAuthenticated()"/> <!--This is the line that is not behaving as expected-->
    <sec:form-login login-page="/data/loginpage"
                    login-processing-url="/data/login"
                    username-parameter="username"
                    password-parameter="password"
                    authentication-failure-handler-ref="authenticationFailureHandler"
                    authentication-success-handler-ref="authenticationSuccessHandler"/>
    <sec:logout logout-url="/data/logout"
                delete-cookies="true"
                invalidate-session="true"
                logout-success-url="/"/>
</sec:http>

<bean id="jsonAuthenticationHandler" class="com.example.security.JsonAuthenticationHandler">
    <constructor-arg name="loginUrl" value="/data/loginpage"/>
</bean>
<bean id="userDetailsService" class="com.example.security.UserDetailService"/>
<bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<bean id="authenticationSuccessHandler" class="com.example.security.AuthenticationSuccessHandler"/>
<bean id="authenticationFailureHandler" class="com.example.security.AuthenticationFailureHandler"/>

<sec:authentication-manager>
    <sec:authentication-provider user-service-ref="userDetailsService">
        <sec:password-encoder ref="encoder"/>
    </sec:authentication-provider>
</sec:authentication-manager>

Thanks in advance for any help!

MrGrinst
  • 970
  • 3
  • 9
  • 20

1 Answers1

2

Assuming you have a form to login you can simple hide it after successful Ajax post or you can use security taglib

<sec:authorize access="isAnonymous()">
    <!-- you form here -->
</sec:authorize>

It will render when there is no user logged in, but when you log you can make a call to render again the view, then the content of these tags will disappear because now the user is authenticated.

These tags render the content based on what role or status of authentication.

Maven dependency:

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-taglibs</artifactId>
    <version>3.2.4.RELEASE</version>
</dependency>
Joao Evangelista
  • 2,407
  • 2
  • 26
  • 37
  • Yeah I realize I will probably just hide the login link if the user is already logged in, but I want to make sure that even if the user does something weird like manually POSTing to the login url, it won't re-authenticate the user. Is there any way to do this on the root level? – MrGrinst Jul 03 '14 at 05:12
  • I found this question http://stackoverflow.com/questions/12637915/spring-security-redirection-issue-for-already-logged-in-users Try write a filter like the second awnser, but change the to you login process url – Joao Evangelista Jul 03 '14 at 05:25
  • and the redirect to your desired url – Joao Evangelista Jul 03 '14 at 05:26
  • I think that's on the right track but here's what I believe is happening. I think because of the way I declare the `form-login`, maybe Spring Security is doing some stuff behind the scenes to set the userPrincipal to null before it hits my filter. I debugged the filter and `getUserPrincipal()` returns nothing. – MrGrinst Jul 03 '14 at 05:44
  • @MrGrinst make sure the filter is positioned after the `springSecurityFilter` in the chain. – Bart Jul 03 '14 at 05:52
  • @Bart It doesn't get called at all if it is... I had to put it above the `springSecurityFilter` just to get it to be called. – MrGrinst Jul 03 '14 at 05:54
  • instead of getUerPrincipal() you can try `SecurityContextHolderAwareRequestWrapper.isUserInRole(String role)` – Joao Evangelista Jul 03 '14 at 05:55
  • @MrGrinst Then you have other problems. The request should go through all filters. – Bart Jul 03 '14 at 05:57
  • Aha, here we go. Looks like this is the issue: http://stackoverflow.com/a/687330/2338117 – MrGrinst Jul 03 '14 at 06:01
  • @MrGrinst I was configuring a new project, then a realize, what about and interceptor on `login-processing-url`? Like `` Only anonymous users e.g. not logged in users can access this url – Joao Evangelista Jul 04 '14 at 18:44