diff --git a/spring-security-rest-full/pom.xml b/spring-security-rest-full/pom.xml index cbcc3fca64..b48d87473b 100644 --- a/spring-security-rest-full/pom.xml +++ b/spring-security-rest-full/pom.xml @@ -238,6 +238,11 @@ spring-test test + + + org.springframework.security + spring-security-test + junit diff --git a/spring-security-rest-full/src/main/java/org/baeldung/spring/SecurityWithCsrfConfig.java b/spring-security-rest-full/src/main/java/org/baeldung/spring/SecurityWithCsrfConfig.java new file mode 100644 index 0000000000..c2a21c3f9e --- /dev/null +++ b/spring-security-rest-full/src/main/java/org/baeldung/spring/SecurityWithCsrfConfig.java @@ -0,0 +1,54 @@ +package org.baeldung.spring; + +import org.baeldung.web.error.CustomAccessDeniedHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.Configuration; +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; + +// @Configuration +// @EnableAutoConfiguration +// @EnableWebSecurity +// @EnableGlobalMethodSecurity(prePostEnabled = true) +public class SecurityWithCsrfConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private CustomAccessDeniedHandler accessDeniedHandler; + + public SecurityWithCsrfConfig() { + super(); + } + + // java config + + @Override + protected void configure(final AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication().withUser("user1").password("user1Pass").authorities("ROLE_USER").and().withUser("admin").password("adminPass").authorities("ROLE_ADMIN"); + } + + @Override + public void configure(final WebSecurity web) throws Exception { + web.ignoring().antMatchers("/resources/**"); + } + + @Override + protected void configure(final HttpSecurity http) throws Exception { + // @formatter:off + http + .authorizeRequests() + .antMatchers("/admin/*").hasAnyRole("ROLE_ADMIN") + .anyRequest().authenticated() + .and() + .httpBasic() + .and() + .exceptionHandling().accessDeniedHandler(accessDeniedHandler) + ; + // @formatter:on + } + +} diff --git a/spring-security-rest-full/src/main/java/org/baeldung/spring/WebConfig.java b/spring-security-rest-full/src/main/java/org/baeldung/spring/WebConfig.java index 19780b1068..143e52d94e 100644 --- a/spring-security-rest-full/src/main/java/org/baeldung/spring/WebConfig.java +++ b/spring-security-rest-full/src/main/java/org/baeldung/spring/WebConfig.java @@ -31,6 +31,7 @@ public class WebConfig extends WebMvcConfigurerAdapter { public void addViewControllers(final ViewControllerRegistry registry) { super.addViewControllers(registry); registry.addViewController("/graph.html"); + registry.addViewController("/csrfHome.html"); } } \ No newline at end of file diff --git a/spring-security-rest-full/src/main/java/org/baeldung/web/controller/BankController.java b/spring-security-rest-full/src/main/java/org/baeldung/web/controller/BankController.java new file mode 100644 index 0000000000..1a4322c611 --- /dev/null +++ b/spring-security-rest-full/src/main/java/org/baeldung/web/controller/BankController.java @@ -0,0 +1,32 @@ +package org.baeldung.web.controller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +// to test csrf +@Controller +public class BankController { + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @RequestMapping(value = "/transfer", method = RequestMethod.GET) + @ResponseBody + public int transfer(@RequestParam("accountNo") final int accountNo, @RequestParam("amount") final int amount) { + logger.info("Transfer to {}", accountNo); + return amount; + } + + // write - just for test + @RequestMapping(value = "/transfer", method = RequestMethod.POST) + @ResponseStatus(HttpStatus.OK) + public void create(@RequestParam("accountNo") final int accountNo, @RequestParam("amount") final int amount) { + logger.info("Transfer to {}", accountNo); + + } +} diff --git a/spring-security-rest-full/src/main/java/org/baeldung/web/error/CustomAccessDeniedHandler.java b/spring-security-rest-full/src/main/java/org/baeldung/web/error/CustomAccessDeniedHandler.java index ae7340ef88..cc07417427 100644 --- a/spring-security-rest-full/src/main/java/org/baeldung/web/error/CustomAccessDeniedHandler.java +++ b/spring-security-rest-full/src/main/java/org/baeldung/web/error/CustomAccessDeniedHandler.java @@ -16,6 +16,7 @@ public class CustomAccessDeniedHandler implements AccessDeniedHandler { @Override public void handle(final HttpServletRequest request, final HttpServletResponse response, final AccessDeniedException ex) throws IOException, ServletException { response.getOutputStream().print("Error Message Goes Here"); + response.setStatus(403); // response.sendRedirect("/my-error-page"); } diff --git a/spring-security-rest-full/src/main/webapp/WEB-INF/view/csrfHome.jsp b/spring-security-rest-full/src/main/webapp/WEB-INF/view/csrfHome.jsp new file mode 100644 index 0000000000..6e6330bad4 --- /dev/null +++ b/spring-security-rest-full/src/main/webapp/WEB-INF/view/csrfHome.jsp @@ -0,0 +1,15 @@ + + + + +

CSRF test on Origin

+ Transfer Money to John + +
+ + + + +
+ + \ No newline at end of file diff --git a/spring-security-rest/src/test/java/org/baeldung/csrf/CsrfAbstractIntegrationTest.java b/spring-security-rest-full/src/test/java/org/baeldung/csrf/CsrfAbstractIntegrationTest.java similarity index 100% rename from spring-security-rest/src/test/java/org/baeldung/csrf/CsrfAbstractIntegrationTest.java rename to spring-security-rest-full/src/test/java/org/baeldung/csrf/CsrfAbstractIntegrationTest.java diff --git a/spring-security-rest/src/test/java/org/baeldung/csrf/CsrfDisabledIntegrationTest.java b/spring-security-rest-full/src/test/java/org/baeldung/csrf/CsrfDisabledIntegrationTest.java similarity index 78% rename from spring-security-rest/src/test/java/org/baeldung/csrf/CsrfDisabledIntegrationTest.java rename to spring-security-rest-full/src/test/java/org/baeldung/csrf/CsrfDisabledIntegrationTest.java index 6705c53ae9..082a37c9f1 100644 --- a/spring-security-rest/src/test/java/org/baeldung/csrf/CsrfDisabledIntegrationTest.java +++ b/spring-security-rest-full/src/test/java/org/baeldung/csrf/CsrfDisabledIntegrationTest.java @@ -3,15 +3,14 @@ package org.baeldung.csrf; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import org.baeldung.spring.ClientWebConfig; -import org.baeldung.spring.SecurityJavaConfig; -import org.baeldung.spring.SwaggerConfig; +import org.baeldung.spring.PersistenceConfig; +import org.baeldung.spring.SecSecurityConfig; import org.baeldung.spring.WebConfig; import org.junit.Test; import org.springframework.http.MediaType; import org.springframework.test.context.ContextConfiguration; -@ContextConfiguration(classes = { SecurityJavaConfig.class, ClientWebConfig.class, WebConfig.class, SwaggerConfig.class }) +@ContextConfiguration(classes = { SecSecurityConfig.class, PersistenceConfig.class, WebConfig.class }) public class CsrfDisabledIntegrationTest extends CsrfAbstractIntegrationTest { @Test diff --git a/spring-security-rest/src/test/java/org/baeldung/csrf/CsrfEnabledIntegrationTest.java b/spring-security-rest-full/src/test/java/org/baeldung/csrf/CsrfEnabledIntegrationTest.java similarity index 88% rename from spring-security-rest/src/test/java/org/baeldung/csrf/CsrfEnabledIntegrationTest.java rename to spring-security-rest-full/src/test/java/org/baeldung/csrf/CsrfEnabledIntegrationTest.java index 721e9e7c52..fe6580bd05 100644 --- a/spring-security-rest/src/test/java/org/baeldung/csrf/CsrfEnabledIntegrationTest.java +++ b/spring-security-rest-full/src/test/java/org/baeldung/csrf/CsrfEnabledIntegrationTest.java @@ -4,15 +4,14 @@ import static org.springframework.security.test.web.servlet.request.SecurityMock import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import org.baeldung.spring.ClientWebConfig; +import org.baeldung.spring.PersistenceConfig; import org.baeldung.spring.SecurityWithCsrfConfig; -import org.baeldung.spring.SwaggerConfig; import org.baeldung.spring.WebConfig; import org.junit.Test; import org.springframework.http.MediaType; import org.springframework.test.context.ContextConfiguration; -@ContextConfiguration(classes = { SecurityWithCsrfConfig.class, ClientWebConfig.class, WebConfig.class, SwaggerConfig.class }) +@ContextConfiguration(classes = { SecurityWithCsrfConfig.class, PersistenceConfig.class, WebConfig.class }) public class CsrfEnabledIntegrationTest extends CsrfAbstractIntegrationTest { @Test diff --git a/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java b/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java index 60866fd2eb..9abe604def 100644 --- a/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java +++ b/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java @@ -42,7 +42,8 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { .authenticationEntryPoint(restAuthenticationEntryPoint) .and() .authorizeRequests() - .antMatchers("/**").authenticated() + .antMatchers("/api/csrfAttacker*").permitAll() + .antMatchers("/api/**").authenticated() .and() .formLogin() .successHandler(authenticationSuccessHandler) diff --git a/spring-security-rest/src/main/java/org/baeldung/spring/SecurityWithCsrfConfig.java b/spring-security-rest/src/main/java/org/baeldung/spring/SecurityWithCsrfConfig.java deleted file mode 100644 index c372a7ca90..0000000000 --- a/spring-security-rest/src/main/java/org/baeldung/spring/SecurityWithCsrfConfig.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.baeldung.spring; - -import org.baeldung.security.MySavedRequestAwareAuthenticationSuccessHandler; -import org.baeldung.security.RestAuthenticationEntryPoint; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -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.web.authentication.SimpleUrlAuthenticationFailureHandler; - -@Configuration -@EnableWebSecurity -@ComponentScan("org.baeldung.security") -public class SecurityWithCsrfConfig extends WebSecurityConfigurerAdapter { - - @Autowired - private RestAuthenticationEntryPoint restAuthenticationEntryPoint; - - @Autowired - private MySavedRequestAwareAuthenticationSuccessHandler authenticationSuccessHandler; - - public SecurityWithCsrfConfig() { - super(); - } - - // - - @Override - protected void configure(final AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication().withUser("temporary").password("temporary").roles("ADMIN").and().withUser("user").password("userPass").roles("USER"); - } - - @Override - protected void configure(final HttpSecurity http) throws Exception {// @formatter:off - http - .exceptionHandling() - .authenticationEntryPoint(restAuthenticationEntryPoint) - .and() - .authorizeRequests() - .antMatchers("/**").authenticated() - .and() - .formLogin() - .successHandler(authenticationSuccessHandler) - .failureHandler(new SimpleUrlAuthenticationFailureHandler()) - .and() - .logout(); - } // @formatter:on - - @Bean - public MySavedRequestAwareAuthenticationSuccessHandler mySuccessHandler() { - return new MySavedRequestAwareAuthenticationSuccessHandler(); - } - - @Bean - public SimpleUrlAuthenticationFailureHandler myFailureHandler() { - return new SimpleUrlAuthenticationFailureHandler(); - } - -} \ No newline at end of file diff --git a/spring-security-rest/src/main/java/org/baeldung/spring/WebConfig.java b/spring-security-rest/src/main/java/org/baeldung/spring/WebConfig.java index 7e1e9cfcc3..2de58c4e15 100644 --- a/spring-security-rest/src/main/java/org/baeldung/spring/WebConfig.java +++ b/spring-security-rest/src/main/java/org/baeldung/spring/WebConfig.java @@ -1,10 +1,14 @@ package org.baeldung.spring; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration @ComponentScan("org.baeldung.web") @@ -16,12 +20,26 @@ public class WebConfig extends WebMvcConfigurerAdapter { } @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { + public void addResourceHandlers(final ResourceHandlerRegistry registry) { registry.addResourceHandler("swagger-ui.html") - .addResourceLocations("classpath:/META-INF/resources/"); + .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**") - .addResourceLocations("classpath:/META-INF/resources/webjars/"); + .addResourceLocations("classpath:/META-INF/resources/webjars/"); + } + + @Bean + public ViewResolver viewResolver() { + final InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); + viewResolver.setPrefix("/WEB-INF/view/"); + viewResolver.setSuffix(".jsp"); + return viewResolver; + } + + @Override + public void addViewControllers(final ViewControllerRegistry registry) { + super.addViewControllers(registry); + registry.addViewController("/csrfAttacker.html"); } } diff --git a/spring-security-rest/src/main/webapp/WEB-INF/view/csrfAttacker.jsp b/spring-security-rest/src/main/webapp/WEB-INF/view/csrfAttacker.jsp new file mode 100644 index 0000000000..2e87d2d07e --- /dev/null +++ b/spring-security-rest/src/main/webapp/WEB-INF/view/csrfAttacker.jsp @@ -0,0 +1,16 @@ + + + + +

CSRF Attacker

+ Show Kittens Pictures + + + +
+ + + +
+ + \ No newline at end of file