Spring Boot+Thymeleaf doesn't resolve login.html - spring

I have basically copied the tutorial to use Spring Web Security with Spring Boot and Thymeleaf. https://spring.io/guides/gs/securing-web/
For configuration:
#Configuration
public class WebConfig implements WebMvcConfigurer {
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.addViewController("/").setViewName("home");
}}
For security in public class WebSec extends WebSecurityConfigurerAdapter:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.antMatchers("/users*").hasRole("ADMIN")
.antMatchers("/users/*").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.logout().permitAll();
}
All html files are under
/src/main/resources/templates
Now, home.html is found nicely. However whenever anything requires the login page, the login.html in the same folder is not found and the error is:
Error resolving template "login", template might not exist or might not be accessible by any of the configured Template Resolvers
I'm not sure how to proceed from here.

Solution: Do not call your template files the same as your routes. The problem can be solved by naming the file login_template.html or something. Or even better, change the line:
registry.addViewController("/login").setViewName("login");
to just
registry.addViewController("/login");
I found a hint to this behaviour in the javadocs for ViewControllerRegistration.setViewName.

Related

TemplateInputeException while trying to serve frontend on my Spring Boot App

Controller Class:
#Controller
public class FirstRestController {
#GetMapping("/")
public String budget() {
return "budget";
}
Security Config:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/h2-console/**").permitAll()
.antMatchers("/api/auth/**").permitAll()
.antMatchers("/").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
}
package structure image
I try to build a frontend for my web application. I'm using the Controller to serve my html Pages. But they are not rendering proberly. I always get a 404 not found Exception.
Now I tried it with Thymeleaf. But i always catch the TemplateInputeException. Thymeleaf is configured in my Pom.xml. I don't know where to debug this. I can't find a typo. So I think it's a bigger configuration I missed. Do I have to configure my resource folder somewhere? How can I server my html frontend pages in the app?
I tried to reinstall Thymeleaf. I already restarted IntelliJ. It tried to use the RequestMapping annotation. I renamed the static folder to public. I tried different paths.

Spring Security redirecting custom login page to itself - Too Many Redirects

I'm currently developing a custom login-page for my Spring Boot Application but I just can't get it to work. Using the default one works fine but as soon as I try to use my custom file, it just repeatedly redirects me until my Browser give up.
Other posts suggest permitting access to the login-path to erveryone but this also doesn't seem to work.
Here is my code:
WebSecurityConfig
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
And Controller for login-page
#Controller
public class WebController {
#GetMapping("/login")
public String login () {
return "login";
}
}
Any ideas what I'm missing?
You are probably using a lot of CSS and JS file link links, according to your code Spring Boot must first authenticate all the links, which is why it redirects to your login page many times.
add following code to bypass security authentication of resource link
public void configure(WebSecurity web) {
web.ignoring()
.antMatchers("/bower_components/**", "/dist/**", "/plugins/**"); //write your resource directory name
}

Spring Security - Redirect to custom login page without going through controller

I am currently using Spring Boot + Spring Security to develop a simple website that need user to login to access it. I have created my own custom static login page under resources/templates1/bruceLogin1.html. Any unathenticated access to my website to first be redirected to the login page URL which is http://localhost:8080/templates1/bruceLogin1.html
Note: that I am NOT creating any controller for this login URL, hence I am expecting the bruceLogin1.html to be accessed directly bypassing controller. Because i directly allow access to this html page without going thru controller, I assume no view resolver (e.g thymleaf) is required.
I open my browser, and enter http://localhost:8080/blablabl, and browser redirect me to http://localhost:8080/templates1/bruceLogin1.html , but sadly, i got error
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sat Jan 11 12:40:37 SGT 2020
There was an unexpected error (type=Not Found, status=404).
No message available
Below is my configuration,
#SpringBootApplication
#EnableWebSecurity
public class SpringSecurityCatalogApplication implements WebMvcConfigurer {
public static void main(String[] args) {
SpringApplication.run(SpringSecurityCatalogApplication.class, args);
}
#EnableWebSecurity
#Order(Ordered.HIGHEST_PRECEDENCE)
class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/templates1/bruceLogin1.html")
.permitAll();
}
}
}
Think instead of putting under resources/template1 folder, i will just put the custom login page into either resources/static or resources/public folder.
Then configure as shown below
#EnableWebSecurity
#Order(Ordered.HIGHEST_PRECEDENCE)
class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/bruceLogin1.html")
.permitAll();
}
}
Open browser and access any URL, you will be redirected to http://localhost:8080/bruceLogin1.html. And thats it!
Note that this does not require any controller nor view resolver.

spring security + spring boot mvc index page before authentication looks like bare html

Before auth
After i log in by any account
Does anyone know what's the matter? No clue.
Seems like your css is not loading for unsecured context. For adding the resources make resource handler entry as below in WebMvcConfigurer
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!registry.hasMappingForPattern(URL_PATTERN_UICONTENT)) {
registry.addResourceHandler(URL_PATTERN_UICONTENT).addResourceLocations("classpath:/uicontent/").setCachePeriod(31556926);
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
}
Problem has been resolved!
I created class
#Configuration
#EnableWebMvc
public class WebMVCConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
}
This way, I say /static/** if any page request by this prefix, so try to find in classpath:static
In my index thymeleaf file i including external css file by:
<link href="../static/css/bootstrap.min.css" th:href="#{static/css/bootstrap.min.css}" rel="stylesheet" />
This example above is shows how to add route where is app should find static resources, but this not necessary actually in my project.
The thing is when you trying to access to static resources before you logged in, you should give the permission to it in WebSecurityConfig class, like this:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/index", "/login","/css/**", "/webjars/**", "/images/**", "/js/**").permitAll()
.antMatchers("/subscribers", "/calldetails").access("hasAnyRole('ROLE_USER', 'ROLE_ADMIN')")
.antMatchers("/divisions").access("hasAnyRole('ROLE_ADMIN')")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.permitAll();

Unauthorized error when using Spring Security and Angular

My frontend is based on Angular 4 and my backend is based on Spring Boot with Spring Security.
I am deploying everything in a single WAR file.
I created a static/landing folder in /src/main/resources and then I put the Webpack-built Angular files in that folder.
Angular is taking care of the login process and so I created the following rule in Spring Security :
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
public WebMvcConfigurerAdapter mappingIndex() {
return new WebMvcConfigurerAdapter() {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("forward:/landing/index.html");
}
};
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
.addFilterBefore(new CORSFilter(),ChannelProcessingFilter.class)
.antMatchers(/"login/**").permitAll()
.anyRequest().authenticated();
Unfortunately, I am always getting the HTTP Status code 401 (Unauthorized) when trying to access the /login page with the webbrowser for signing in.
How can I achieve to integrate the Angular App in this way ? Because my Security rules are working fine with the REST Apis.
.antMatchers(/"login/**").permitAll() looks wrong,
try this:
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.authorizeRequests()
.antMatchers("/login/**").permitAll()
.anyRequest().authenticated();
}
if it still doesn't work, add to your application.properties
logging.level.org.springframework.security=trace
logging.level.org.springframework.web=trace
and post output

Resources