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
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
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");
}
}
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 ?
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
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/**")
...