paul_oshea
paul_oshea

Reputation: 65

Thymeleaf and Spring boot and Spring security not working

I am trying to run thymeleaf, spring security and spring boot together, but i am unsure how to integrate it all as I've had some issues with spring security blocking the hrefs of statics etc.

The problem is after submitting the login it doesnt go through the successhandler of the security config so I think the views are not being mapped correctly.

SecurityConfig looks like this:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private static final Logger logger = LogManager.getLogger(SecurityConfig.class);

    @Autowired
    private LoggingAccessDeniedHandler accessDeniedHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers(
                        "/",
                        "/js/**",
                        "/css/**",
                        "/img/**",
                        "/webjars/**").permitAll()
                .antMatchers("/user/**").hasRole("USER")
                .anyRequest().authenticated()
            .and()
            .formLogin()
                .loginPage("/login")
                .successHandler(myAuthenticationSuccessHandler())
                .permitAll()
            .and()
            .logout()
                .invalidateHttpSession(true)
                .clearAuthentication(true)
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/login?logout")
                .permitAll()
            .and()
            .exceptionHandling()
                .accessDeniedHandler(accessDeniedHandler);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web
            .ignoring()
            .antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**","/vendor/**","/fonts/**");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        logger.info("configuring");
        auth.inMemoryAuthentication()
            .withUser("user").password("password").roles("USER")
            .and()
            .withUser("manager").password("password").roles("MANAGER");
    }

    @Bean
    public AuthenticationSuccessHandler myAuthenticationSuccessHandler(){
        logger.info("GOt into the thingie");
        return new MySimpleUrlAuthenticationSuccessHandler();
    }
}

class MySimpleUrlAuthenticationSuccessHandler
    implements AuthenticationSuccessHandler {

    private static final Logger logger = LogManager.getLogger(SecurityConfig.class);

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
        HttpServletResponse response, 
        Authentication authentication)
        throws IOException {

        handle(request, response, authentication);
        clearAuthenticationAttributes(request);
    }

    protected void handle(HttpServletRequest request,
        HttpServletResponse response, Authentication authentication)
        throws IOException {

        logger.info("got here");
        String targetUrl = determineTargetUrl(authentication);

        if (response.isCommitted()) {
            logger.info(
                "Response has already been committed. Unable to redirect to " + targetUrl);
            return;
        }

        redirectStrategy.sendRedirect(request, response, targetUrl);
    }

    protected String determineTargetUrl(Authentication authentication) {
        logger.info("got here in target");
        boolean isUser = false;
        boolean isAdmin = false;
        Collection<? extends GrantedAuthority> authorities
            = authentication.getAuthorities();
        for (GrantedAuthority grantedAuthority : authorities) {
            if (grantedAuthority.getAuthority().equals("ROLE_USER")) {
            isUser = true;
            break;
            } else if (grantedAuthority.getAuthority().equals("ROLE_ADMIN")) {
                isAdmin = true;
                break;
            }
        }

        if (isUser) {
            return "/homepage.html";
        } else if (isAdmin) {
            return "/console.html";
        } else {
            throw new IllegalStateException();
        }
    }

    protected void clearAuthenticationAttributes(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session == null) {
            return;
        }
        session.removeAttribute
            (WebAttributes.AUTHENTICATION_EXCEPTION);
    }

    public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
        this.redirectStrategy = redirectStrategy;
    }
    protected RedirectStrategy getRedirectStrategy() {
        return redirectStrategy;
    }
}

Controller looks like this:

@RequestMapping(value = "/", method= RequestMethod.GET)
public String login(Model model){
    return "login";
}

@RequestMapping(value = "/login", method= RequestMethod.GET)
public String loginSucc(Model model){
    return "predictions";
}

under src/main/resources/templates are:

templates html

As can be seen from the above image I have all the required html pages under template. ** Predictions.html is there too just not included in the screenshot. Finally the login.html looks like this:

<!-- Login Form -->
<form th:action="@{/login}" method="post">
    <input type="text" id="login" class="fadeIn second" name="login" placeholder="login">
    <input type="text" id="password" class="fadeIn third" name="login" placeholder="password">
    <input type="submit" class="fadeIn fourth" value="Log In">
</form>

After getting the login page and putting in any username and password it redirects to the predictions page. It is clearly not authenticating as the username/password is not being checked and also in the predictions page I print out the username that is just not appearing(blank). I have added the snippet as per the comment below. But it makes no difference.

Predictions page after redirection from "login.html" : enter image description here

Upvotes: 0

Views: 2629

Answers (2)

paul_oshea
paul_oshea

Reputation: 65

Problem was with the input type name it was login instead of username:

This fixed it:

  <form th:action="@{/login}" method="post">
            <input type="text" id="username" class="fadeIn second" name="username" placeholder="login">
            <input type="text" id="password" class="fadeIn third" name="password" placeholder="password">

Upvotes: -1

Aritra Paul
Aritra Paul

Reputation: 874

override this method configure(WebSecurity web) too and modifie code like below

 @Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/user/**").hasRole("USER")
                .anyRequest().authenticated()
                .and()
                .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/module",true)
            .failureUrl("/login?error=true")
        .permitAll();// others according to your need
    }
      @Override
        public void configure(WebSecurity web) throws Exception {
            web
                    .ignoring()
                    .antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**","/vendor/**","/fonts/**");
        }
}

Upvotes: 1

Related Questions