I want to check captcha if use wants to be logined and if captcha was correct, call filterChain.doFilter()
to resume authentication and if captcha was incorrect rediredt user to login page to re-enter username, password and captcha.
So, i want to put my CaptchaFilter
with /login filterMapping
in the first of spring securtiy fiter chain.
login.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html; charset=UTF-8" language="java" pageEncoding="UTF-8" session="true" %>
<html>
<head>
<title>Login Page</title>
</head>
<body onload='document.loginForm.username.focus();'>
<div id="login-box">
<form name='loginForm' action="<c:url value='/login' />" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='username'></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='password'/>
</td>
</tr>
<tr>
<td colspan="2">
<img id="imgCaptcha" src="<c:url value = '/j-captcha.jpg' />" onclick='this.src="<c:url value='/j-captcha.jpg'/>";' style="cursor: pointer"/>
</td>
</tr>
<tr>
<td colspan="2">
<input name="jcaptcha" type="text" placeholder="captcha"/>
</td>
<tr>
<td colspan='2'><input name="submit" type="submit" value="submit"/></td>
</tr>
</table>
</form>
</div>
</body>
</html>
CaptchaFilter
public class CaptchaFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
if (request.getParameter("jcaptcha") != null) {
checkCaptcha(request, response, filterChain);
} else {
filterChain.doFilter(request, response);
}
}
private void checkCaptcha(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
try {
String userCaptchaResponse = request.getParameter("jcaptcha");
boolean isResponseCorrect = CaptchaService.getInstance().validateResponseForID(request.getRequestedSessionId(), userCaptchaResponse);
if (isResponseCorrect) {
filterChain.doFilter(request, response);
} else {
String url = request.getHeader("referer").replaceAll("[&?]error.*?(?=&|\\?|$)", "");
url += "?error=" + SecurityUtility.CAPTCHA_IS_WRONG;
redirect(request, response, url);
}
} catch (Exception e) {
e.printStackTrace();
filterChain.doFilter(request, response);
}
}
private void redirect(HttpServletRequest request, HttpServletResponse response, String url) {
try {
response.sendRedirect(request.getContextPath() + url);
} catch (Exception ex) {
ex.printStackTrace();
}
}
@Override
public void destroy() {
}
}
SpringSecurityConfig:
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("userDetailsService")
UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/admin/**")
.access("hasRole('ROLE_USER')").and().formLogin()
.loginPage("/login").failureUrl("/login?error")
.usernameParameter("username")
.passwordParameter("password")
.and().logout().logoutSuccessUrl("/login?logout")
.and().exceptionHandling().accessDeniedPage("/403");
}
}
SpringWebConfig
@EnableWebMvc
@Configuration
@ComponentScan({"com.rgh.*"})
@EnableTransactionManagement
@Import({SpringSecurityConfig.class})
public class SpringWebConfig {
@Bean
public SessionFactory sessionFactory() {
LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(dataSource());
builder.scanPackages("com.rgh.*.model").addProperties(getHibernateProperties());
return builder.buildSessionFactory();
}
private Properties getHibernateProperties() {
// set and return properties
}
@Bean(name = "dataSource")
public BasicDataSource dataSource() {
// set and return datasource
}
@Bean
public HibernateTransactionManager txManager() {
return new HibernateTransactionManager(sessionFactory());
}
}
SpringWebInitializer
public class SpringWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringWebConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/", "/rest/*"};
}
}
SpringSecurityInitializer
public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}
i'm new to spring 4 and spring java config.