5

I am using spring security 3.1 for my web application.

I have implemented my custom filter for providing filtering of requested URL.

Once user is logged in and then user hits log in URL, at that time log in URL should not be opened. I mean to say how can I check that user is already logged in or not?

If user is already logged in, log in page should not be opened. It should open default-target-url page.

Thanks.

Harshal Patel
  • 51
  • 1
  • 3

4 Answers4

4

I was looking for a solution to exact same problem. I ended up doing the following:

@RequestMapping(method = RequestMethod.GET, value = "/admin/login")
public ModelAndView login(HttpServletRequest request) {
    Object principal =  SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    if(principal instanceof UserDetails && validLogin((UserDetails) principal)){
        return new ModelAndView("redirect:/admin/home"); // Go to admin home if already
                                                         // logged in
    }

    final String error = request.getParameter("login_error");
    return loginPage.display(error); // Not logged in, so admin login page is displayed
}

private boolean validLogin(UserDetails userDetails) {
    // This function does a check to ascertain the validity of the logged in user
    // You may also consider evaluating userDetails.getAuthorities()
    return userDetails.isAccountNonExpired() &&
            userDetails.isAccountNonLocked() &&
            userDetails.isCredentialsNonExpired() &&
            userDetails.isEnabled();
}

But i sure hope there is a more configurable way to achieve this.

imdahmd
  • 737
  • 1
  • 6
  • 15
4

You can use the static method in the SecurityContextHolder class to get the Security Context from where you can get the Authentication object and then you can find whether a user is currently logged in or not.

Samarth Bhargava
  • 4,196
  • 3
  • 17
  • 16
  • Thanks for your answer. But my problem is that If user is already logged in then login page should not be displayed. Instead of Login page main page(coming after login page) should be displayed. So please help me out to solve this problem using preauthentication filter, if it's possible. Thanks. – Harshal Patel Mar 12 '12 at 07:06
0

I am writing similar functionality right now. In my case i just added this code to spring security configuration:

<http pattern="/**" auto-config="false" use-expressions="true" >

<intercept-url pattern="/login" access="!isAuthenticated()" />
<access-denied-handler error-page="/"/>

<!--    More configuration here -->

</http>

Of course this configuration redirects all "denied access" requests to your main page. If you want different redirect for your login page only, you should deliver your own access-denied-handler implementation.

0

Try this:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null) {
//not authorized
}
Object principalObject = authentication.getPrincipal();
if (principalObject == null) {
//not authorized
}

Or you can configure the security, I think this is what you need in your applicationContext:

<security:http auto-config="true" authentication-manager-ref="authenticationManager">
        <!-- Don't set any role restrictions on login.jsp and index.jsp -->
        <security:intercept-url pattern="/login"
                                access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <security:intercept-url pattern="/urlOfAView"
                                access="IS_AUTHENTICATED_ANONYMOUSLY"/>

        <!-- Restrict access to ALL other pages -->
        <security:intercept-url pattern="/**" access="ROLE_USER"/>

        <!-- Set the login page and what to do if login fails -->
        <security:form-login login-page="/login"
                             authentication-failure-url="/login?login_error=1" default-target-url="/loginUser"/>

        <!-- Set the logout page and where to go after logout is successful -->
        <security:logout logout-success-url="/index"/>
    </security:http>

I use Spring 3.1 so my namespaces are:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:security="http://www.springframework.org/schema/security"
       xsi:schemaLocation="
       http://www.springframework.org/schema/security 
       http://www.springframework.org/schema/security/spring-security-3.1.xsd
       http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       ">

Good luck

Sinisha Mihajlovski
  • 1,811
  • 1
  • 20
  • 34
  • Thanks for your answer. But my problem is that If user is already logged in then login page should not be displayed. Instead of Login page main page(coming after login page) should be displayed. So please help me out to solve this problem using preauthentication filter, if it's possible. Thanks. – Harshal Patel Mar 12 '12 at 07:06
  • I updated my answer. If you add the configuration to the application context, when you visit the index page, spring will check if you are authenticated. If you are not it will redirect you to the login page. You can also see: [Security Namespace Configuration](http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html) – Sinisha Mihajlovski Mar 12 '12 at 08:42
  • thanks for your reply. But I want it also vice-verse. I mean to say if user is already logged in, then login page will not be opened but target url will be open. Thanks. – Harshal Patel Mar 15 '12 at 13:13
  • This should also work vice versa. If i understand correctly, you want to redirect to /index from /login if the user is already logged in? I dont know how you have solved the login page, but you should be able to check if the user is logged in then just redirect to /index. In the controller just check if (loggedIn()) return "index". That should solve it. – Sinisha Mihajlovski Mar 19 '12 at 12:53