简体   繁体   中英

Spring Security for single user

I have a web application in which a specific url '/newPost' should only be accessible to one user, the admin. When trying to navigate to '/newPost', the user should be redirected to a login page where he must verify his identity as admin.

This all works, except for when the user fills out the login form, the form gets posted to '/login' everytime. I am currently at a loss as to why it is posting to '/login' instead of the path I redirect to using thyme leafs: th:action="@{/newPost}"

TLDR; I keep getting redirected to /login after submitting login form. I am using Spring boot, Spring security, and thymeleaf.

Controller:

/*Keeps getting called*/
@RequestMapping(value="/login", method=RequestMethod.GET)
public String login(Model model)
{   
    model.addAttribute("lc", new LoginCredentials());
    System.out.println("Login controller");
    return "login";
}

/*RequestMapping I want to be called*/
@RequestMapping(value="/newPost", method = RequestMethod.GET)
public String isLoggedIn(@ModelAttribute LoginCredentials lc, Model model)
{
    if(lc.isAdmin())
    {
        System.out.println("lc is admin");
        model.addAttribute("bp",new BlogPost());
        return "newPost";
    } else
    {
        System.out.println("lc is not admin");
        return "login";
    }
}

Login Form:

 <form class="form-signin" th:action="@{/newPost}" th:object="${lc}" method = "post">
    <h2 class="form-signin-heading">Please sign in</h2>
    <label for="inputEmail" class="sr-only">Username</label>
    <input type="text" id="username" class="form-control" th:field="*{inputUsername}" placeholder="Username" required="required" autofocus="autofocus" />
    <label for="inputPassword" class="sr-only">Password</label>
    <input type="password" id="password" th:field="*{inputPsswd}" class="form-control" placeholder="Password" required ="required" />

    <button class="btn btn-lg btn-primary btn-block" type="submit" style="background-color:#F6358A;">Sign in</button>
  </form>

Security Configuration:

    httpSecurity
    .authorizeRequests()
      .antMatchers("/","/videos","/BlogPost","/index","/aboutUs").permitAll()
      .anyRequest().authenticated()
      .and()
    .formLogin()
      .loginPage("/login")
      .permitAll();

What's your login page jsp name? Is that "login.jsp"?

You login method return is "login", that means it will return to login.jsp.

User return "/newPost" instead.

My above question was a mess. This was my first time trying to work with Java Spring and my question shows. I hope this explanation helps a future user.

Firstly:

The action should not be different from /login. I was essentially causing an infinite loop of logins because I was sending the user to /newPost by submitted the login form, but they could not access the /newPost until they provided the correct credentials. Spring dutifully redirected the user to /login in order to provide the correct credentials, repeating the process.

This:

th:action="@{/newPost}"

should be:

 th:action="@{/login}"

with a corresponding RequestMapping like so:

@RequestMapping(value="/login", method=RequestMethod.POST)
public String loginPost(Model model)
{   
 //do foo
}

Secondly:

I attempted to do Spring Security's job for it.

 if(lc.isAdmin())
{
    System.out.println("lc is admin");
    model.addAttribute("bp",new BlogPost());
    return "newPost";
} else
{
    System.out.println("lc is not admin");
    return "login";
}

Since I only needed security for a single user, I should have configured an AuthenticationManagerBuilder object in my security configuration like so:

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
{
  try 
  {
    auth 
        .inMemoryAuthentication()
          .withUser("admin")
            .password("password")
            .roles("ADMIN");
  } catch (Exception e) {
    e.printStackTrace();
  }
}

Since I changed Springs global configuration, I should not pass in an object to login.html. The new form should use input fields like so:

 <form class="form-signin" th:action="@{/login}" method = "post">
    <h2 class="form-signin-heading">Please sign in</h2>
    <label for="inputEmail" class="sr-only">Username</label>
    <input type="text" id="username" name="username" class="form-control" placeholder="Username" required="required" autofocus="autofocus" />
    <label for="inputPassword" class="sr-only">Password</label>
    <input type="password" id="password"  name="password" class="form-control" placeholder="Password" required ="required" />

    <button class="btn btn-lg btn-primary btn-block" type="submit" style="background-color:#F6358A;">Sign in</button>
  </form>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM