Reputation: 65
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:
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
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
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