I have struggling to configure security for some different paths I have.
I would like this structure:
/actuator/health <-- open
/api/** <-- hasAnyAuthority
/auth/** <-- basic authentication
all others no access
So far this is what I have
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/**") // If you want to override the security provided by Spring Boot.
.addFilter(preAuthFilter())
.cors()
.and()
.csrf().disable()
.authorizeRequests()
.antMatchers("/actuator/health").permitAll()
.antMatchers("/api/**").hasAnyAuthority("something")
.antMatchers("/auth/**").authenticated()
.and()
.httpBasic();
}
I would like to add .anyRequest().denyAll() but that doesn't seem to be possible after httpBasic().
Can anyone confirm that the above code will be the same as what I would like?
Example on how to split configuration by path:
#Configuration
public class ApiSecurityConfiguration extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/api/**")
.authorizeRequests()
.antMatchers("/api/public/**", "/api/register").anonymous() //if you need to allow some path in api
.antMatchers("/api/**", "/api/register/**").hasRole("API_USER")
.and()
.formLogin()
.loginPage("/api/")
.failureHandler(failureHandler())
.loginProcessingUrl("/api/login")
.usernameParameter("username")
.passwordParameter("password")
.successHandler(successHandler())
.and()
.logout()
.logoutUrl("/api/logout")
.logoutSuccessUrl("/api/")
.invalidateHttpSession(true)
.and()
.rememberMe()
.key("something")
.and()
.csrf().disable()
.exceptionHandling()
.accessDeniedPage("/api/loginfailed");
}
}
Second path:
#Configuration
public class AuthSecurityConfiguration extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/auth/**")
.authorizeRequests()
.antMatchers("/auth/register").anonymous()
.antMatchers("/auth/**", "/auth/register/**").hasRole("USER")
.and()
.formLogin()
.loginPage("/auth/")
.failureHandler(failureHandler())
.loginProcessingUrl("/auth/login")
.usernameParameter("username")
.passwordParameter("password")
.successHandler(successHandler())
.and()
.logout()
.logoutUrl("/auth/logout")
.logoutSuccessUrl("/auth/")
.invalidateHttpSession(true)
.and()
.rememberMe()
.key("something")
.and()
.csrf().disable()
.exceptionHandling()
.accessDeniedPage("/auth/loginfailed");
}
}
Now since you have not added security for /actuator/health you can either leave it without one or you can make another adapter for it and permit access to everyone.
Also you should use csrf protection, it is easy to implement.
Related
I am making enterprise webapp, i have built my custom login page but somehow only spring security login page is coming instead of my custom login page. Below is my security configuration class.
please help.
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().withUser("test").password("pwd123")
.roles("USER", "ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/", "/*todo*/**").access("hasRole('USER')").and()
.formLogin();
http.csrf().disable();
}
You have to specify the url to your custom login page.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/", "/*todo*/**").access("hasRole('USER')").and()
.formLogin()
// put the relative URL to your custom login here
.loginPage("/login")
.permitAll();
http.csrf().disable();
}
Hope this helps.
Look every thing good, this is work for me:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/todo/**").hasRole("USER")
.antMatchers("/", "/home").permitAll()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home")
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/home")
.permitAll()
.and()
.exceptionHandling().accessDeniedPage("/403");
}
Here is a Spring Boot project.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests().antMatchers("/login").permitAll()
.anyRequest().authenticated().and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home")
.failureUrl("/login?error=true")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login?logout=true")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.permitAll();
}
Reference : https://devkonline.com/tutorials/content/SPRING-SECURITY-5-CUSTOM-FORM-LOGIN-THYMELEAF
I am getting 403 on every request having pattern /admin
I need to restrict /admin only for admin role.
Failed approach :
Tried using #PreAuthorize(hasRole('ADMIN')) and #PreAuthorize(hasRole('ROLE_ADMIN')) on controller but no luck.
Tried removing #PreAuthorize from controller and adding pattern in the below class with hasRole but no luck
Below is the class extends WebSecurityConfigurerAdapter
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
#Autowired
AuthenticationEntryPoint authenticationEntryPoint;
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS).permitAll()
.antMatchers(HttpMethod.GET,"/admin/**").hasAnyRole("ADMIN","ADMIN_TENANT")
.anyRequest().authenticated()
.and()
.logout()
.permitAll()
.and()
.csrf()
.disable();
httpSecurity.
addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
httpSecurity.
headers().cacheControl().disable();
}
Already tried solutions mentioned in similar question but no luck.
So please don't mark it duplicate.
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
#Autowired
AuthenticationEntryPoint authenticationEntryPoint;
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS).permitAll()
.antMatchers(HttpMethod.GET,"/admin/**").hasAnyRole("ADMIN","ADMIN_TENANT") // change hasAnyrole to hasAnyAuthority
.anyRequest().authenticated()
.and()
.logout()
.permitAll()
.and()
.csrf()
.disable();
httpSecurity.
addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
httpSecurity.
headers().cacheControl().disable();
}
My similar Git Project: here
// Config to check if already active
http.authorizeRequests()
.and()
.rememberMe()
.tokenRepository(new JdbcTokenRepositoryImpl().setDataSource(//datasource_name) )
.tokenValiditySeconds(//TimeInterval in sec);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.and()
.httpBasic()
.and()
.csrf().disable()
.authorizeRequests()
//cia apsirasau tuos endpointus kuriuos leidziu neprisijungus:
.antMatchers("/admin/login", "/admin/register","/teams").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(unauthorizedHabdler)
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtauthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
This is mys configure method, the problem is that I want lets say allow to access /teams endpoint for everyone, but when I start my program and go to /teams endpoint it asks for authentification. Where is the problem?
i want to stay in the same page after login but spring oblige u to redirect to defaultSuccessUrl
my code is like this
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/css/**","/fonts/**","/js/**","/app/**","/images/**","/partials/**").permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/index.html")
.failureUrl("/login?error=true")
.permitAll()
.and().logout().logoutSuccessUrl("/login?logout")
.and().exceptionHandling().accessDeniedPage("/pages/303.html");
}
Set
always-use-default-target="true"
which will force spring-security to go to /index.html
I think you should add an authentication success handler
#Override
protected void configure(HttpSecurity http) throws Exception {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setUseReferer(true);//redirect to the previous page
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/css/**","/fonts/**","/js/**","/app/**","/images/**","/partials/**").permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/index.html")
.failureUrl("/login?error=true")
.permitAll()
.successHandler(successHandler)//enable success handler
.and().logout().logoutSuccessUrl("/login?logout")
.and().exceptionHandling().accessDeniedPage("/pages/303.html");
}
Anyone knows how to configure a customized 403 page in spring security? Looking in the web, all the results I get it's with XML configuration, and I am using Java configuration. That's my SecurityConfig:
#Configuration
#ComponentScan(value="com")
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return new CustomAuthenticationManager();
}
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/resources/**", "/publico/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/acesso/login").permitAll()
.loginProcessingUrl("/login").permitAll()
.usernameParameter("login")
.passwordParameter("senha")
.successHandler(new CustomAuthenticationSuccessHandler())
.failureHandler(new CustomAuthenticationFailureHandler())
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/acesso/login").permitAll();
}
}
I have a custom implementation for AccessDeniedHandler too:
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
#Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException arg2) throws IOException, ServletException {
response.sendRedirect(request.getContextPath() + "/erro/no_permit");
}
}
If I'm right, to personalize the page 403, you could use the model implemented by this server.
Spring Security : Customize 403 Access Denied Page
Example:
AppConfig.java
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**", "/signup").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.logout().logoutUrl("/logout").logoutSuccessUrl("/")
.and()
.rememberMe()
.and()
.csrf().disable();
}
HomeController.java
#RequestMapping("/403")
public String accessDenied() {
return "errors/403";
}
And the .html, would be a custom page with some message 403.