8

When the root controller ("/") is called, I want to check if the user has authenticated or not. If he is not authenticated I want to display home page while if he is I want to display dashboard like so:

@GetMapping("/")
public String homePage() {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

    if(authentication == null) return "home";

    return "dashboard";
}

But when I run the program, it tries to display dashboard, which means that clearly the if() condition returned false. But I know that I definitely did not log in. Why does this not work.

Also, I know I could override the configure(HttpSecurity http) method in the WebSecurityConfigurerAdapter like so:

http.authorizeRequests().antMatchers("/").authenticated();

But this would redirect me to the /login page, which is ok for any other request but not ("/") where I want to be redirected to "home" page if no session exists.

This is the value of authentication after a Sysout: org.springframework.security.authentication.AnonymousAuthenticationToken@52132976: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS

YeetCoder
  • 304
  • 1
  • 3
  • 12

3 Answers3

14

You have to disable anonymous authentication, see HttpSecurity#anonymous:

The following demonstrates how to represent anonymous users as null. Note that this can cause NullPointerException in code that assumes anonymous authentication is enabled.

@Configuration
@EnableWebSecurity
public class AnononymousSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/**").hasRole("USER").and().formLogin()
                            .and()
                            // sample anonymous customization
                            .anonymous().disabled();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
              auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
    }
}

or you could check for class AnonymousAuthenticationToken. Your modified code:

@GetMapping("/")
public String homePage() {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

    if (authentication instanceof AnonymousAuthenticationToken) return "home";

    return "dashboard";
}
dur
  • 15,689
  • 25
  • 79
  • 125
  • There is no method called "disabled()" after .anonymous() Rather a method called "disable()" is there. Do you mean to refer to that method? – YeetCoder Jul 16 '19 at 11:42
  • I tried the first method(with .disable()) but it caused problems. But the second method worked perfectly for me. – YeetCoder Jul 16 '19 at 11:46
  • @YeetCoder You are right, it is an error in Spring Security's API Doc. I guess it should be `disable`. – dur Jul 16 '19 at 17:48
1

Well, the fastest way to do so (worked with me in my app) is the following:

@GetMapping("/")
public Boolean isLoggedIn(Principal principal) {

    if(principal == null) return "home";

    return "dashboard";
}

It should be noted that in my app I already configured all the security stuff. This means that if my solution won't work with you (hope not), know that you have to configure all the security stuff too (check Spring Security courses).

Yves
  • 252
  • 3
  • 6
0

With the current version of spring security, you could add a role of anonymous authenticated user in the security configuration class; then restrict that role for accessing paths requiring not anonymous.

sdrkyj
  • 75
  • 1
  • 10