I want to see the login page first even any user want access any other page need to redirect to login page in spring security - spring-boot

Here is the sample controller. My problem is basically when i am entering the base url it is redirecting to inner page not in the log in page. What i want. What should i do to achieve this.
Here is the sample controller. My problem is basically when i am entering the base url it is redirecting to inner page not in the log in page. What i want. What should i do to achieve this.
package com.sushovan.security.controller;
import javax.validation.groups.ConvertGroup;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class HomeController {
#RequestMapping("/")
public String home() {
return "home.jsp";
}
#RequestMapping("/login")
public String loginPage() {
return "login.jsp";
}
#RequestMapping("/logout-success")
public String logoutPage() {
return "logout.jsp";
}
}
Here is the sample Security Configuration class.Mostly all configuration have been done here.
package com.sushovan.security.config;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.AntPathMatcher;
#Configuration
#EnableWebSecurity
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
/**This is for authentication from database**/
#Bean
public AuthenticationProvider authProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(userDetailsService);
//provider.setPasswordEncoder(NoOpPasswordEncoder.getInstance());//This is for not use any encryption
provider.setPasswordEncoder(new BCryptPasswordEncoder());//This is for BCryptPasswordEncoder
return provider;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests().antMatchers("/login")
.permitAll()
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("userName").passwordParameter("password")
.permitAll()
.and()
.logout().invalidateHttpSession(true)
.clearAuthentication(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/logout-success").permitAll();
}
}

Spring security filters algorithm works like this ;
is web resource protected ?
is user authenticated ?
is user authorized ?
So if its not authenticated it redirect request to login page, which is what you want.
So you should update your configure method
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("userName").passwordParameter("password")
.permitAll()
.and()
.logout().invalidateHttpSession(true)
.clearAuthentication(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/logout-success").permitAll();
}
can you please try this and let me know if it works ?

Related

The dependencies of some of the beans in the application context form a cycle:

2022-12-31T00:48:58.789+05:30 ERROR 10168 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
┌──->──┐
| authenticationManager defined in class path resource [com/ecommerce/admin/config/AdminConfiguration.class]
└──<-──┘
Action:
Despite circular references being allowed, the dependency cycle between beans could not be broken. Update your application to remove the dependency cycle.
Process finished with exit code 0
package com.ecommerce.admin.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
#EnableWebSecurity
#Configuration
public class AdminConfiguration {
#Bean
public UserDetailsService userDetailsService() {
return new AdminServiceConfig();
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public AuthenticationManager authenticationManager(AuthenticationManager authenticationManager) throws Exception {
return authenticationManager;
}
#Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(userDetailsService());
provider.setPasswordEncoder(passwordEncoder());
return provider;
}
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/do-login")
.defaultSuccessUrl("/admin/index")
.permitAll()
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login/logout")
.permitAll();
DefaultSecurityFilterChain build = http.build();
return build;
}
}
package com.ecommerce.admin.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
#EnableWebSecurity
#Configuration
public class AdminConfiguration {
#Bean
public UserDetailsService userDetailsService() {
return new AdminServiceConfig();
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public AuthenticationManager authenticationManager(AuthenticationManager authenticationManager) throws Exception {
return authenticationManager;
}
#Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(userDetailsService());
provider.setPasswordEncoder(passwordEncoder());
return provider;
}
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/do-login")
.defaultSuccessUrl("/admin/index")
.permitAll()
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login/logout")
.permitAll();
DefaultSecurityFilterChain build = http.build();
return build;
}
}
Circular dependency issue is coming because of this Bean present inside AdminConfiguration class. Here in method argument you are passing an instance of AuthenticationManager and also creating another instance of AuthenticationManager using #Bean annotation. This is incorrect, please remove this and try again.
#Bean
public AuthenticationManager authenticationManager(AuthenticationManager authenticationManager) throws Exception {
return authenticationManager;
}

The method antMatchers(String) is undefined for the type

package com.codewitheshan.blog.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.codewitheshan.blog.security.CustomUserDetailService;
import com.codewitheshan.blog.security.JwtAuthenticationEntryPoint;
import com.codewitheshan.blog.security.JwtAuthenticationFilter;
#Configuration
#EnableWebSecurity
public class SecurityConfig {
#Autowired
private CustomUserDetailService customUserDetailService;
#Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
#Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeHttpRequests()
.antMatchers("/api/v1/auth/login").permitAll()
.anyRequest()
.authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(this.jwtAuthenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(this.jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(this.customUserDetailService).passwordEncoder(passwordEncoder());
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public AuthenticationManager authenticationManagerBean(AuthenticationConfiguration configuration) throws Exception {
return configuration.getAuthenticationManager();
}
}
There is error showing in antMatchers
**I'm getting an error for "antMatchers". It is not recognised. I have tied searching but did not get any thing related to this.
Error is:
The method antMatchers(String) is undefined for the type AuthorizeHttpRequestsConfigurer.AuthorizationManagerRequestMatcherRegistry
How to fix it? **
This method has changed to :
.requestMatchers({your-matcher})
So, in your case :
http
.csrf()
.disable()
.authorizeHttpRequests()
.requestMatchers("/api/v1/auth/login").permitAll()
.anyRequest()
.authenticated()
// ...
More information : https://docs.spring.io/spring-security/reference/servlet/authorization/authorize-http-requests.html
I hope this has helped you

How to only check for Authentication by "Bearer" header in Spring Boot using Spring Security?

I want to authenticate a server. I want to make sure the user is giving a header key, I am not checking for login or anything.
I want the header key to check with my hardcoded one,
If its equal pass it,
Else no
I wrote two filters.
SecurityConfig.java
package com.company.framework.filter;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
#Configuration
#EnableWebSecurity
public class SecurityConfig{
#Autowired private AuthFilter filtet;
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
System.out.println("reaching here3 ");
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/v1/open/**").permitAll()
.and()
.exceptionHandling()
.authenticationEntryPoint(
(request, response, authException) ->
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error here")
)
.and()
.sessionManagement()
.and()
.httpBasic().disable();
http
.addFilter(filtet);
return http.build();
}
}
Authfilter.java
package com.company.framework.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
#Component
public class AuthFilter extends OncePerRequestFilter{
#Override
protected void doFilterInternal(HttpServletRequest request,HttpServletResponse response,FilterChain filterChain) throws ServletException, IOException {
String authHeader = request.getHeader("Authorization");
System.out.println("here ");
System.out.println(authHeader+"1");
if (authHeader != null && authHeader.length() == 0 && authHeader.startsWith("Bearer ")) {
String jwt = authHeader.substring(7);
System.out.println(authHeader+"2");
if (jwt == null) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid JWT Token in Bearer Header");
} else {
String rev = "bfrek";
if (jwt.equals(rev)) {
response.setStatus(200);
} else {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid JWT Token");
}
}
}
filterChain.doFilter(request, response);
}
}
But, after all days of try and error, I am still getting 401 unauthorised.
I have seen articles telling how to connect it with users database but I just want to check for header token and pass it through. (Using filter)
Edit 1:
Now after reading many articles and documentation, I understand that there are 15 filters, But how do I make sure that the system just checks for my header key and ignore everything else.
Seems you missed overriding the configure method of WebSecurityConfigurerAdapter class. This is the main logic to override the default spring security logic. This is the main problem i guess. try to extend that class(WebSecurityConfigurerAdapter) and override that method(configure) in SecurityConfig.java.
SecurityConfig.java
package com.company.framework.filter;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurer{
#Autowired private AuthFilter filtet;
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
System.out.println("reaching here3 ");
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/v1/open/**").permitAll()
.and()
.exceptionHandling()
.authenticationEntryPoint(
(request, response, authException) ->
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error here")
)
.and()
.sessionManagement()
.and()
.httpBasic().disable();
http.addFilter(filtet);
return http.build();
}
}

Spring security configure issue

Here is my configuration in security and the problem is all the requests such as /v3/api-docs will be redirected to /login or /register.I don't know why and Please help.
package reg.example.confgure;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import reg.example.model.User;
import reg.example.service.UserRepositoryUserDetailService;
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private UserRepositoryUserDetailService userDetailsService;
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/v3/api-docs",
"/swagger-resources/configuration/ui",
"/swagger-resources",
"/swagger-resources/configuration/security",
"/swagger-ui.html");
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(this.userDetailsService)
.passwordEncoder(User.PASSWORD_ENCODER);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
// 关闭csrf防护
.csrf().disable()
.headers().frameOptions().disable()
.and()
.authorizeRequests()
.antMatchers("/user/**").permitAll()
.antMatchers("/v3/api-docs", "/swagger-resources/configuration/ui",
"/swagger-resources", "/swagger-resources/configuration/security",
"/swagger-ui.html", "/webjars/**").permitAll()
.antMatchers("/", "/login","/register").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
package reg.example.confgure;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
public class MvcConfig implements WebMvcConfigurer {
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.addViewController("/register").setViewName("register");
}
}

Thymeleaf tries to authenticate again when loading template from a controller

I want to render a navigation view from a controller using Thymeleaf. However, the navigation should be based on user's authorities so I do not want to exclude it from Spring Security. I therefore use a UrlTemplateResolver:
package it.vertyze.platform.web.controllers;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.templateresolver.UrlTemplateResolver;
#Configuration
public class VZMVCConfig extends WebMvcConfigurerAdapter {
#Autowired
private SpringTemplateEngine templateEngine;
#PostConstruct
public void templateResolverExtension(){
UrlTemplateResolver urlTemplateResolver = new UrlTemplateResolver();
urlTemplateResolver.setOrder(20);
templateEngine.addTemplateResolver(urlTemplateResolver);
}
}
However, when I log into my site, the link does not even get resolved. Instead, I am being redirected to the login page. When I disable the security, I get a template not found error, so the template resolver does not render the controller's output, but when I navigate to it, it renders precisely the HTML I want.
Here is my security config:
package it.vertyze.platform.web.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
#Configuration
#EnableWebMvcSecurity
public class VZWebSecurityConfig extends WebSecurityConfigurerAdapter{
#Autowired
VZUserDetailsService userDetailsService;
#Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(userDetailsService).passwordEncoder(encoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception{
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
#Bean
public PasswordEncoder encoder(){
return new BCryptPasswordEncoder();
}
}
And here is where I call the link in the enclosing template:
<div th:replace="${topNavLinks.getHref()}"></div>

Resources