Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaConfiguration for Spring 4.0 + Security 3.2 + j_spring_security_check

  1. Create a login page

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="ISO-8859-1">
            <title>Test</title>
            <script src="static/js/jquery-1.10.2.min.js"></script>
            <script src="static/js/app-controller.js"></script>
        </head>
        <body>
            <div>Login</div>
            <form name="f" action="<c:url value="/j_spring_security_check"/>" method="POST">
                <label for="password">Username</label>&nbsp;<input type="text" id="j_username" name="j_username"><br/>
                <label for="password">Password</label>&nbsp;<input type="password" id="j_password" name="j_password"><br/>
                <input type="submit" value="Validate">&nbsp;<input name="reset" type="reset">
                <input type="hidden" id="${_csrf.parameterName}" name="${_csrf.parameterName}" value="${_csrf.token}"/>
            </form>
            <hr/>
            <c:if test="${param.error != null}">
                <div>
                    Failed to login.
                    <c:if test="${SPRING_SECURITY_LAST_EXCEPTION != null}">
                      Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />
                    </c:if>
                </div>
            </c:if>
            <hr/>
            <input type="button" value="Echo" id="echo" name="echo" onclick="AppController.echo();">
            <div id="echoContainer"></div>
    
        </body>
    </html>
    
  2. Declare a WebSecurityConfigurer HERE IS WHERE I WAS MISSING j_username AND j_password

    @Configuration
    @EnableWebSecurity
    @ComponentScan(basePackages = {"com.sample.init.security"})
    public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
    
        @Inject
        private AuthenticationProvider authenticationProvider;
    
        @Inject
        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(authenticationProvider);
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                    .antMatchers(
                            "/resources/**", 
                            "/static/**", 
                            "/j_spring_security_check", 
                            "/AppController/echo.html").permitAll()
                    .anyRequest().authenticated()
                    .and()
                .formLogin()
                    .usernameParameter("j_username") /* BY DEFAULT IS username!!! */
                    .passwordParameter("j_password") /* BY DEFAULT IS password!!! */
                    .loginProcessingUrl("/j_spring_security_check")
                    .loginPage("/")
                    .defaultSuccessUrl("/page")
                    .permitAll()
                    .and()
                .logout()
                    .permitAll();
        }
    
        @Override
        public void configure(WebSecurity web) throws Exception {
            web
                .ignoring()
                    .antMatchers("/static/**");
        }
    
    }
    
  3. Declare a WebMvcConfigurer

    @EnableWebMvc
    @Configuration
    @ComponentScan(basePackages = {
            "com.app.controller",        
            "com.app.service",
            "com.app.dao"
    })
    public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
    
        @Bean
        public ViewResolver viewResolver() {
            InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
            viewResolver.setPrefix("/WEB-INF/view/");
            viewResolver.setSuffix(".jsp");
            return viewResolver;
        }
    
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
          registry.addViewController("/page").setViewName("page");
        }
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("static/**").addResourceLocations("static/");
        }
    
    }
    
  4. Declare a Security Initializer

    public class SecurityWebAppInitializer 
        extends AbstractSecurityWebApplicationInitializer { }
    
  5. Declare an App Initialzer

    public class Initializer extends AbstractAnnotationConfigDispatcherServletInitializer  {
    
        @Override
        protected Class<?>[] getRootConfigClasses() {       
            return new Class<?>[]{WebSecurityConfigurer.class};
        }
    
        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class<?>[]{WebMvcConfigurer.class, DataSourceConfigurer.class};
        }
    
        @Override
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
    
    }
    
  6. Implement your custom Authentication Provider

    @Component
    @ComponentScan(basePackages = {"com.app.service"})
    public class CustomAuthenticationProvider implements AuthenticationProvider {
    
        private static final Logger LOG = LoggerFactory.getLogger(CustomAuthenticationProvider.class);
    
        @Inject
        private AppService service;
    
        @Override
        public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    
            //Thread.dumpStack();
            String username = authentication.getName();
            String password = authentication.getCredentials().toString();
    
            String message = String.format("Username: '%s' Password: '%s'", username, password);
            UserBean userBean = service.validate(username, password);       
            LOG.debug(message);
            if (userBean != null) {
                List<GrantedAuthority> grantedAuths = new ArrayList<>();
                grantedAuths.add(new SimpleGrantedAuthority("USER"));
                return new UsernamePasswordAuthenticationToken(userBean, authentication, grantedAuths); 
            } else {
                String error = String.format("Invalid credentials [%s]", message);
                throw new BadCredentialsException(error);
            }
        }
    
        @Override
        public boolean supports(Class<?> authentication) {
            return authentication.equals(UsernamePasswordAuthenticationToken.class);
        }
    
    }
    

I am skipping EchoController, AppService, AppDao and UserBean.

Thanks.

like image 988
zeh Avatar asked Dec 20 '13 13:12

zeh


People also ask

What is J_spring_security_check?

j_spring_security_check is a Servlet where the actual authentication is made and you must map the action of your login form to this Servlet.

How do I add security dependency in spring?

For adding a Spring Boot Security to your Spring Boot application, we need to add the Spring Boot Starter Security dependency in our build configuration file. Maven users can add the following dependency in the pom. xml file. Gradle users can add the following dependency in the build.

How do I limit the number of login attempts in Spring Security?

Solution. Review the existing Spring Security's authentication class, the “locked” feature is already implemented. To enable the limit login attempts, you need to set the UserDetails. isAccountNonLocked to false.

How do I enable HTTP Security in spring?

The first thing you need to do is add Spring Security to the classpath. The WebSecurityConfig class is annotated with @EnableWebSecurity to enable Spring Security's web security support and provide the Spring MVC integration.


1 Answers

In 3.2 version post parameters have changed from j_username to username and j_password to password. The login url has also changed from /j_spring_security_check to /login.

See this link for the explanation of why this change was implemented: http://docs.spring.io/spring-security/site/docs/3.2.0.RELEASE/reference/htmlsingle/#jc-httpsecurity. These are the changes:

  • GET /login renders the login page instead of /spring_security_login

  • POST /login authenticates the user instead of /j_spring_security_check

  • The username parameter defaults to username instead of j_username

  • The password parameter defaults to password instead of j_password

And this for an example of a login form: http://docs.spring.io/spring-security/site/docs/3.2.0.RELEASE/reference/htmlsingle/#jc-form

like image 131
pasemes Avatar answered Nov 10 '22 07:11

pasemes