Bogdan Zeleniuk Bogdan Zeleniuk - 1 month ago 20
Java Question

spring security gives the error while redirecting to logout.jsp

I have the


ERR_TOO_MANY_REDIRECTS


exception while redirecting to logout.jsp page. I think I give this exception because of wrong spring security config file but I don`t know where is it. If somebody know, how to fix it, than please tell me.
What does it mean? My code:

spring security config:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/**").access("IS_AUTHENTICATED_ANONYMOUSLY")
.antMatchers("/**").access("hasRole('ROLE_USER')")
.antMatchers("/login").permitAll()
.antMatchers("/register").permitAll()
.antMatchers("/logout").permitAll()
.antMatchers("/js/**", "/css/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/j_spring_security_check")
.failureForwardUrl("/login?error=true")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/logout")
.permitAll();

}
}


logout buttom:

<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<a class="navbar-brand">Contacts List</a>

<div class="collapse navbar-collapse">
<form class="navbar-form navbar-right">
<li>
<a class="btn btn-primary" role="button" href="logout">Logout</a>
</li>
</form>
</div>
</div>
</div>

and login.jsp:
<html>
<jsp:include page="headTag.jsp"/>
<body>
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li>
<c:url value="/j_spring_security_check" var="loginUrl"/>
<form:form class="navbar-form" role="form" action="${loginUrl}"
method="post">
<div class="form-group">
<label for="username"> Login: </label>
<div class="col-sm-3">
<input type="text" placeholder="Login" class="form-control" name='username' id="username">
</div>
</div>
<div class="form-group">
<label for="password"> Password: </label>
<div class="col-sm-3">
<input type="password" placeholder="Password" class="form-control" name='password' id="password">
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-success">Sign in</button>
</div>
</form:form>
<br/>
<form class="navbar-form" action="<c:url value="register.jsp" />">
<button class="btn btn-sm btn-block btn-primary" role="button">Register</button>
</form>
</li>
</ul>
</div>
</div>
</div>
<div class="jumbotron">
<div class="container">
<c:if test="${not empty error}">
<div class="error">${error}</div>
</c:if>
<c:if test="${not empty logout}">
<div class="message">${logout}</div>
</c:if>

<p>
<br/><br/><br/><br/>
<p>User login: <b> Bill </b></p>
<p>User password: <b> 112233 </b></p>

<p>Стек технологий: <a href="http://projects.spring.io/spring-security/">Spring Security</a>,
<a href="http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html">Spring MVC</a>,
<a href="http://projects.spring.io/spring-data-jpa/">Spring Data JPA</a>,
<a href="http://spring.io/blog/2014/05/07/preview-spring-security-test-method-security">Spring Security
Test</a>,
<a href="http://hibernate.org/orm/">Hibernate ORM</a>,
<a href="http://hibernate.org/validator/">Hibernate Validator</a>,
<a href="http://www.slf4j.org/">SLF4J</a>,
<a href="https://github.com/FasterXML/jackson">Json Jackson</a>,
<a href="http://ru.wikipedia.org/wiki/JSP">JSP</a>,
<a href="http://en.wikipedia.org/wiki/JavaServer_Pages_Standard_Tag_Library">JSTL</a>,
<a href="http://tomcat.apache.org/">Apache Tomcat</a>,
<a href="http://www.webjars.org/">WebJars</a>,
<a href="http://datatables.net/">DataTables plugin</a>,
<a href="http://ehcache.org">Ehcache</a>,
<a href="http://www.postgresql.org/">PostgreSQL</a>,
<a href="http://junit.org/">JUnit</a>,
<a href="http://hamcrest.org/JavaHamcrest/">Hamcrest</a>,
<a href="http://jquery.com/">jQuery</a>,
<a href="http://ned.im/noty/">jQuery notification</a>,
<a href="http://getbootstrap.com/">Bootstrap</a>.</p>
</div>
</div>
<jsp:include page="footer.jsp"/>
</body>
</html>


Controller:

@Controller
public class RootController extends AbstractUserController implements ErrorController {

private static final String PATH = "/error";

@RequestMapping(value = "/", method = RequestMethod.GET)
public String root() {
return "redirect:/contacts";
}

@RequestMapping(value = "/contacts", method = RequestMethod.GET)
public String contactList() {
return "contacts";
}

@RequestMapping(value = "/login", method = {RequestMethod.GET, RequestMethod.POST})
@PreAuthorize("hasRole('ROLE_USER')")
public String login(Model model, @RequestParam(value = "error", required = false) boolean error){
model.addAttribute("error", error);
return "login";
}

@RequestMapping(value="/logout", method = {RequestMethod.GET, RequestMethod.POST})
public String logoutPage (HttpServletRequest request, HttpServletResponse response) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null){
new SecurityContextLogoutHandler().logout(request, response, auth);
}
return "logout";
}

@RequestMapping(value = "/register", method = RequestMethod.GET)
public String register(ModelMap model) {
model.addAttribute("userDTO", new UserDTO());
model.addAttribute("register", true);
return "register";
}

@RequestMapping(value = PATH)
public String error(){
return "redirect:/login";
}

@RequestMapping(value = "/register", method = RequestMethod.POST)
public String saveRegister(@Valid UserDTO userDTO, BindingResult result, SessionStatus status, ModelMap model) {
if (!result.hasErrors()) {
try {
super.create(UserUtil.createNewUserFromDTO(userDTO));
status.setComplete();
return "redirect:login?message=app.registered";
} catch (DataIntegrityViolationException ex) {
result.rejectValue("Login", "---");
}
}
model.addAttribute("register", true);
return "contacts";
}

@Override
public String getErrorPath() {
return PATH;
}
}


Thanks guys.

dur dur
Answer

With request /logoutyou process the logout and after successful logout you redirect to /logout, which tries another logout.

See LogoutConfigurer#logoutUrl

The URL that triggers log out to occur (default is "/logout"). If CSRF protection is enabled (default), then the request must also be a POST. This means that by default POST "/logout" is required to trigger a log out. If CSRF protection is disabled, then any HTTP method is allowed.

and LogoutConfigurer#logoutSuccessUrl

The URL to redirect to after logout has occurred.

You have to use two different URLs for processing and successful logout. The first URL must no exist and is only for the LogoutFilter. The second has to be implemented by your application.