Spring security configure issue - spring-boot

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");
}
}

Related

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

Spring can't load css before login, but after login everything is ok

When I run the app my login page is without images, but when I log in and log out, the login page is styled as it should be.
Can problem be the Security file or something else?
All answers i found are related to the problem where spring won't load CSS at all (.antMatchers(" resources/", "/static/", "/css/", "/js/", "/images/**")) but I don't think this is the same. I couldn't find solution for this.
This is my security file:
package com.example.dnevnikjartest.configuration;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
private AuthenticationSuccessHandler authenticationSuccessHandler;
#Autowired
public SecurityConfiguration(AuthenticationSuccessHandler authenticationSuccessHandler) {
this.authenticationSuccessHandler = authenticationSuccessHandler;
}
#Autowired
private DataSource dataSource;
#Value("${spring.queries.users-query}")
private String korisniciQuery;
#Value("${spring.queries.roles-query}")
private String ulogeQuery;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().usersByUsernameQuery(korisniciQuery).authoritiesByUsernameQuery(ulogeQuery)
.passwordEncoder(bCryptPasswordEncoder).dataSource(dataSource);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/resource/**").permitAll()
.antMatchers("/roditelj/**").hasAuthority("roditelj")
.antMatchers("/admin/**").hasAuthority("admin")
.antMatchers("/ucitelj/**").hasAuthority("ucitelj")
.antMatchers("/direktor/**").hasAuthority("direktor")
.anyRequest()
.authenticated().and().csrf().disable().formLogin().loginPage("/login").failureUrl("/login?error=true")
.successHandler(authenticationSuccessHandler)
.usernameParameter("username")
.passwordParameter("password").and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/").and()
.exceptionHandling().accessDeniedPage("/access-denied");
}
}
}
I found a solution to my own question.
I insert this code in the class I mentioned in the question and I created folder images in resource -> static. Previously I have all files images files and .css mixed directly in static without folders.
String[] staticResources = {
"/css/**",
"/images/**",
"/fonts/**",
"/scripts/**",};
This is how whole class looks now
package com.example.dnevnikjartest.configuration;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
private AuthenticationSuccessHandler authenticationSuccessHandler;
#Autowired
public SecurityConfiguration(AuthenticationSuccessHandler authenticationSuccessHandler) {
this.authenticationSuccessHandler = authenticationSuccessHandler;
}
#Autowired
private DataSource dataSource;
#Value("${spring.queries.users-query}")
private String korisniciQuery;
#Value("${spring.queries.roles-query}")
private String ulogeQuery;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().usersByUsernameQuery(korisniciQuery).authoritiesByUsernameQuery(ulogeQuery)
.passwordEncoder(bCryptPasswordEncoder).dataSource(dataSource);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
String[] staticResources = {
"/css/**",
"/images/**",
"/fonts/**",
"/scripts/**",};
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/resource/**").permitAll()
.antMatchers("/roditelj/**").hasAuthority("roditelj")
.antMatchers("/admin/**").hasAuthority("admin")
.antMatchers("/ucitelj/**").hasAuthority("ucitelj")
.antMatchers(staticResources).permitAll()
.anyRequest()
.authenticated().and().formLogin().loginPage("/login").failureUrl("/login?error=true")
.successHandler(authenticationSuccessHandler)
.usernameParameter("username")
.passwordParameter("password").and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/").and()
.exceptionHandling().accessDeniedPage("/access-denied");
}
}

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

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 ?

How to migrate code from Spring Security to Reactive Spring Security?

I'm trying to migrate classic Spring Boot Application to Reactive Spring Boot Application, but I have a problems with this task.
How to migrate the code below
package com.example;
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.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
#Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api").anonymous()
.antMatchers("/api/**").authenticated().and()
.httpBasic();
http
.authorizeRequests()
.antMatchers("/login").anonymous()
.antMatchers("/", "/error", "/**/favicon.ico", "/css/**", "/fonts/**", "/js/**", "/images/avatar.png", "/images/logo.png", "/profile", "/profile/find", "/profile/view/**", "/api/register").permitAll()
.anyRequest().authenticated().and()
.formLogin().loginPage("/login").loginProcessingUrl("/profile/login").failureUrl("/login?error").usernameParameter("usr").passwordParameter("pass").and()
.logout().logoutUrl("/logout").invalidateHttpSession(true).deleteCookies("jsessionid","nebp").logoutSuccessUrl("/login?logout").and()
.rememberMe().key("nebpps").tokenValiditySeconds(2419200).rememberMeParameter("remember_me").rememberMeCookieName("nebp").useSecureCookie(true).and()
.csrf().ignoringAntMatchers("/api/**").and()
.exceptionHandling().accessDeniedPage("/403");//.and()
//.requiresChannel().anyRequest().requiresSecure();
}
#Bean(name = "passwordEncoder")
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
to style code like below
#Configuration
#EnableWebFluxSecurity
public class SecurityConfiguration {
#Bean
SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
return http
.csrf().disable()
.authorizeExchange()
.pathMatchers("/login", "/logout").permitAll()
.pathMatchers("/i18n/**",
"/css/**",
"/fonts/**",
"/icons-reference/**",
"/img/**",
"/js/**",
"/vendor/**").permitAll()
.anyExchange()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.and()
.logout()
.logoutUrl("/logout")
.and()
.build();
}
//in case you want to encrypt password
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
I accepted that certain elements can not be defined as before like usernameParameter.
First of all, how to set that the given path (/logout) is only for anonymous users.
Secondly, how to have CSRF enabled, but to have exclusion for addresses beginning with /api

Spring boot Security URL Configuration

I have set the root path as:-
server.contextPath=/myspringBootApp (in Application.propertes) file.
and changed the configuration file as:-
package com.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
#Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
public CustomAuthenticationEntryPoint unauthorizedHandler;
#Autowired
MyDaoAuthenticationProvider authProvider;
#Bean
public CustomAuthenticationTokenFilter authenticationTokenFilterBean() {
return new CustomAuthenticationTokenFilter();
}
#Autowired
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider.authProvider());
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf().disable()
.authorizeRequests()
// UI related urls
.antMatchers(
HttpMethod.GET,
"/",
"/myspringBootApp/login",
"/content/**",
"/*.html",
"/favicon.ico",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/assets/**"
).permitAll()
//Back end - auth layer
.antMatchers("/auth/user").permitAll()
//Back end - actual rest layer
.antMatchers(HttpMethod.POST,"/auth/login").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler);
httpSecurity.addFilterBefore(authenticationTokenFilterBean(),UsernamePasswordAuthenticationFilter.class)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
The above code is not working and loading the UI. I tried changing the UI URLs to /myspringBootApp/favicon.ico, but this also dint give desired result.
Can anyone help me to find a solution?
I think you can use the WebSecurity part of the WebSecurityConfigurerAdapter for this:
#Override
public void configure(final WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/")
.antMatchers("/favicon.ico")
.antMatchers("/**.css")
.antMatchers("/webjars/**")
...

Resources