Spring Boot, Azure Active Directory, 404 Not Found Page - spring-boot

I am trying run azure active directory for my spring boot with web services. The problem is when I login successfully, it can not find a page that should be reachable.
I have added following properties (tetant-id, client-id, client-secret, user-group.allowed-group-names) with
azure.activedirectory.redirect-uri-template=login/oauth2/code
and my configuration is:
#Order(1)
#Configuration
#EnableWebSecurity
public class AADSecurityConfiguration extends AADWebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/health");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/oauth2/**", "/login/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.oauth2Login()
.defaultSuccessUrl("/list", true);
}
}
simple controller request is:
#GetMapping("/list")
#PreAuthorize("hasRole('Admin') or hasRole('Users')")
public String getListPage() {
return "list";
}
versions of the dependencies are:
<spring.security.version>5.6.0</spring.security.version>
<spring.boot.version>2.5.4</spring.boot.version>
<azure.version>3.10.0</azure.version>
I have already added redirects URIs like
as I mentioned when I login properly, /list page is not reachable, it shows 404 error below.
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sat Nov 27 12:29:06 UTC 2021
There was an unexpected error (type=Not Found, status=404).
What could be a reason for that issue ?

Please check if below can be possible workarounds
In some cases,problem maybe the location of the Application startup class .Place the Application class on the outermost side,so that it contains all the subpackages.
Try to put application class ( which contain main method) at the root of controllers's package.(The purpose is to make the application contain all sub packages )
(or)
Error is due to Bootstrap class is not aware of the location of the controller where it needs to be looked.
Try adding in class level annotation in your main class: #ComponentScan(basePackages = {(name of your controller package)}
#ComponentScan(basePackages={"com.sample.controller"})
#SpringBootApplication
(Or)
Try adding thymeleaf dependency in pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Note: Also make sure ,if spring boot redirect url has to use the Azure
AD starter in this scenario, Set the redirect
URI to /login/oauth2/code/. For example:
http://localhost:8080/login/oauth2/code/. Be sure to include the
trailing /
Try to clear the cache and try again.
References:
spring-oauth-2-0-client-returns-401-unauthorized
spring-boot-SO

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 - 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 boot Whitelabel page error for unauthorized ldap group access

I'm developing a web application in spring boot 2.0.0 and spring security 5.0.6 and I've had perfect luck with it until I added some logic that validates that the user is part of an LDAP group. If the user provides invalid credentials, the login page is shown again with a validation error displayed, but when the credentials are correct but the user is not part of the required LDAP group, the application is redirected to a Whitelabel Error Page that, along with that title in bold letters shows this:
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Fri Feb 22 18:40:55 EST 2019
There was an unexpected error (type=Forbidden, status=403).
Forbidden
This is the correct error, so I know the authentication is working. But I want to stay on the login page and not redirect, and I cannot figure out how to do that.
My entire configure method for my WebSecurityConfigurerAdapter is shown here below:
#Override
protected void configure(HttpSecurity http) throws Exception {
// Disabling CSRF because it causes issues with API requests (POSTs don't
// contain the CSRF tokens).
http.csrf().disable();
http.headers().frameOptions().disable();
http.authorizeRequests()
// This line turns off authentication for all management endpoints, which means all
// endpoints that start with "/actuator" (the default starter path for management endpoints
// in spring boot applications). To selectively choose which endpoints to exclude from authentication,
// use the EndpointRequest.to(String ... method, as in the following example:
// .requestMatchers(EndpointRequest.to("beans", "info", "health", "jolokia")).permitAll()
.requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
// Do not authenticate resource requests
.antMatchers(
"/app/css/**",
"/app/img/**",
"/app/js/**",
"/app/bootstrap/**").permitAll()
.antMatchers(
"/admin/**",
"/app/builds/**",
"/app/monitor/**",
"/app/review/**")
.hasRole(requiredRole)
// All other requests are authenticated
.anyRequest().authenticated()
// Any unauthenticated request is forwarded to the login page
.and()
.formLogin()
.loginPage(LOGIN_FORM)
.permitAll()
.successHandler(successHandler())
.and()
.exceptionHandling()
.authenticationEntryPoint(delegatingAuthenticationEntryPoint())
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher(LOGOUT_FORM))
.logoutSuccessUrl(LOGIN_FORM);
}
I'm open to critique of the construct of this entire method, btw--I've taken over this project and this is new to me. This code was working perfectly before I introduced the 6 lines ending with .hasRole(requiredRole), and it still works as long as the user is part of the required group.
I haven't provided the source for some of the methods that are called here, and I'm happy to paste them if someone would like. I'm guessing someone that knows this stuff well will spot the problem right away.
Any advice would be appreciated.
The solution I landed upon is similar to those I've found by googling around. I created an error controller that resolves to /error. At first I didn't think my error handler was ever being reached because I wasn't properly configured in my editor to debug a spring boot application, but I resolved that this morning. I added an error controller that looks like this:
#Controller
public class MyErrorController implements ErrorController {
private static final String ERROR_PATH = "/error";
#Autowired
private ErrorAttributes errorAttributes;
#RequestMapping(value = ERROR_PATH)
public String error(WebRequest request, HttpServletRequest httpServletRequest) {
Map<String, Object> attrs = this.errorAttributes.getErrorAttributes(request, false);
Integer status = (Integer) attrs.get("status");
if (status != null && status == 403) {
httpServletRequest.setAttribute("unauthorized", true);
}
return "/app/login";
}
#Override
public String getErrorPath() {
return ERROR_PATH;
}
}
So whenever an unauthorized attempt is made, this controller is hit and the condition of a status 403 triggers the logical branch in this method. I added the request attribute "unauthorized" and forward to the login jsp page, to which I've added a section that detects the presence of the request attribute. Voila, I'm all set.

custom login page for spring security oauth2 client login

I'm trying to implement social login in my spring boot 2 app with a custom login page. I place spring-boot-starter-oauth2-client as a dependency in my pom.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
I then provide some client id and secret details in my application properties file..
spring.security.oauth2.client.registration.google.client-id=client-id
spring.security.oauth2.client.registration.google.client-secret=client-secret
With this minimal code spring boot registers the client and provides a login page with a link to login via the client. Now I want to provide my own login page so I have created a Seurity config..
#Configuration
#EnableWebSecurity(debug = false)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/auth/**", "/login/oauth2/**", "/login**", "/logout", "/**/*.css", "/**/*.js").permitAll()
.anyRequest().authenticated()
.and()
.oauth2Login().loginPage("/login")
.and()
.logout();
}
}
I then provide a controller to serve up my custom login page, I have just put this in my spring boot config for now..
#SpringBootApplication
#Controller
public class SingleSignonApplication {
public static void main(String[] args) {
SpringApplication.run(SingleSignonApplication.class, args);
}
#RequestMapping("/login")
public String loginPage() {
return "login.html";
}
}
..and my login page (simplified) provides links to login via google..
<a class="btn btn-block btn-social btn-google" href="/oauth2/authorization/google"><span class="fab fa-google"></span> Sign in with Google</a>
Now when I sign in via this button, it calls google, is authenticated and then when its redirected to login/oauth2/code/google... I get a 404 page not found. Also /logout stops working. Do I need to manually configure the other stuff as I realise I am relying on spring boot to continue setting up the clients listed in the app propertie file and set up a client repository automatically.

401 unauthorized page for swagger?

I am enable swagger2 by #EnableSwagger2. However, when I try to hit "/swagger-ui.html", it first hit my Authentication Filter. Then, I wrote the following code to bypass the authentication check
String resourcePath = new UrlPathHelper().getPathWithinApplication(httpRequest);
if ("/swagger-ui.html".equalsIgnoreCase(resourcePath)) {
filterChain.doFilter(request, response);
}
I can see the filterChain.doFilter(request, response); was hit. However, when I let the debug go, it returns a page with information below
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Wed Apr 04 15:41:50 EDT 2018
There was an unexpected error (type=Unauthorized, status=401).
No message available
Any idea, guys?
I encountered the same issue in my project and discovered this solution, so first add this config file to the project
package bla.bla.conf;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#Configuration
#EnableSwagger2
public class Swagger2Config {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors
.basePackage("bla.bla.controllers"))
.paths(PathSelectors.any())
.build();
}
}
and then add this code block to you WebSecurityConfig
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().mvcMatchers(HttpMethod.OPTIONS, "/**");
web.ignoring().mvcMatchers("/swagger-ui.html/**", "/configuration/**", "/swagger-resources/**", "/v2/api-docs","/webjars/**");
}
my problem fixed
source : swagger.io
Think you can add your ownWebSecurityConfig extends WebSecurityConfigurerAdapter, than override configure(WebSecurity web) method and there put web.ignoring().antMatchers("/swagger-ui.html") ofc annotate that class with #Configuration
I have the same error and I add this code inside the class websecurityConfig
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/test/**").permitAll() // permit the class of test
.antMatchers("/**").permitAll() // permit all the routers after swagger-ui.html
.anyRequest().authenticated();
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
As answered by Georgi Stoyanov , adding that much code removed Whitelabel Error Page error but my swagger UI home page was blank as there was 401 issue in loading some css & js files.
Swagger-ui with Spring security
Also, important point that I want to mention is that my swagger UI was working for Weblogic deployment without above code (only HttpSecurity override was enough ) and I was facing issue only when running app in embedded tomcat.
Spring Boot Version : 1.5.2.RELEASE
SpringFox Version 2.8.0
So I had to made code changes as answered by me in linked question to load all CSS & JS files also.
I had the same problem and this was my solution.
if do you have a Spring security config, you must to give authorization at all urls that swagger needs
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers(HttpMethod.POST,"/api/loggin").permitAll()
.antMatchers(HttpMethod.GET,"/swagger-resources/**").permitAll()
.antMatchers(HttpMethod.GET,"/swagger-ui/**").permitAll()
.antMatchers(HttpMethod.GET,"/v2/api-docs").permitAll()
.anyRequest()
.authenticated();
}
and in your class main you shuld to add this notation
#EnableSwagger2
and finally in yor pom.xml this dependencies.
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
for use http://localhost:8090/swagger-ui/

Resources