diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/AppInitializer.java b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/AppInitializer.java new file mode 100644 index 0000000000..43921f71a2 --- /dev/null +++ b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/AppInitializer.java @@ -0,0 +1,11 @@ +package com.baeldung.exceptionhandler; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AppInitializer { + public static void main(String[] args) { + SpringApplication.run(AppInitializer.class, args); + } +} diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/AccessDeniedController.java b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/AccessDeniedController.java new file mode 100644 index 0000000000..0973fe1ad3 --- /dev/null +++ b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/AccessDeniedController.java @@ -0,0 +1,15 @@ +package com.baeldung.exceptionhandler.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/access-denied") +public class AccessDeniedController { + + @GetMapping + public String accessDenied() { + return "/denied.html"; + } +} diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/CustomErrorController.java b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/CustomErrorController.java new file mode 100644 index 0000000000..8b65a623eb --- /dev/null +++ b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/CustomErrorController.java @@ -0,0 +1,15 @@ +package com.baeldung.exceptionhandler.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping +public class CustomErrorController { + + @GetMapping("/customError") + public String customErrorController() { + return "/error"; + } +} diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/HomeController.java b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/HomeController.java new file mode 100644 index 0000000000..d64bf7b5f3 --- /dev/null +++ b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/HomeController.java @@ -0,0 +1,15 @@ +package com.baeldung.exceptionhandler.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/home") +public class HomeController { + + @GetMapping + public String home() { + return "/index.html"; + } +} diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/SecuredResourceController.java b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/SecuredResourceController.java new file mode 100644 index 0000000000..a057570e29 --- /dev/null +++ b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/controller/SecuredResourceController.java @@ -0,0 +1,15 @@ +package com.baeldung.exceptionhandler.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/secured") +public class SecuredResourceController { + + @GetMapping + public String secureResource() { + return "/admin.html"; + } +} diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/CustomAccessDeniedHandler.java b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/CustomAccessDeniedHandler.java new file mode 100644 index 0000000000..a3d6aca9be --- /dev/null +++ b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/CustomAccessDeniedHandler.java @@ -0,0 +1,17 @@ +package com.baeldung.exceptionhandler.security; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; + +public class CustomAccessDeniedHandler implements AccessDeniedHandler { + + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exc) throws IOException { + response.sendRedirect("/access-denied"); + } +} diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationFailureHandler.java b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationFailureHandler.java new file mode 100644 index 0000000000..281f9d5289 --- /dev/null +++ b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationFailureHandler.java @@ -0,0 +1,17 @@ +package com.baeldung.exceptionhandler.security; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; + +public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler { + + @Override + public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException { + httpServletResponse.sendRedirect("/customError"); + } +} diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationSuccessHandler.java b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationSuccessHandler.java new file mode 100644 index 0000000000..62cbdf8873 --- /dev/null +++ b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationSuccessHandler.java @@ -0,0 +1,31 @@ +package com.baeldung.exceptionhandler.security; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; + +public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler { + + @Override + public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { + + HttpSession session = httpServletRequest.getSession(); + User authUser = (User) SecurityContextHolder.getContext() + .getAuthentication() + .getPrincipal(); + session.setAttribute("username", authUser.getUsername()); + session.setAttribute("authorities", authentication.getAuthorities()); + + httpServletResponse.setStatus(HttpServletResponse.SC_OK); + + httpServletResponse.sendRedirect("/home"); + } +} diff --git a/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/SecurityConfig.java b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/SecurityConfig.java new file mode 100644 index 0000000000..71ded0f131 --- /dev/null +++ b/spring-security-modules/spring-security-core/src/main/java/com/baeldung/exceptionhandler/security/SecurityConfig.java @@ -0,0 +1,98 @@ +package com.baeldung.exceptionhandler.security; + +import org.springframework.context.annotation.Bean; +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.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; + +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Bean + public UserDetailsService userDetailsService() { + + UserDetails user = User.withUsername("user") + .passwordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder()::encode) + .password("password") + .roles("USER") + .build(); + + UserDetails admin = User.withUsername("admin") + .passwordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder()::encode) + .password("password") + .roles("ADMIN") + .build(); + + InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager(); + + userDetailsManager.createUser(user); + userDetailsManager.createUser(admin); + + return userDetailsManager; + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication() + .withUser("user") + .password("{noop}password") + .roles("USER") + .and() + .withUser("admin") + .password("{noop}password") + .roles("ADMIN"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.csrf() + .disable() + .httpBasic() + .disable() + .authorizeRequests() + .antMatchers("/login") + .permitAll() + .antMatchers("/customError") + .permitAll() + .antMatchers("/access-denied") + .permitAll() + .antMatchers("/secured") + .hasRole("ADMIN") + .anyRequest() + .authenticated() + .and() + .formLogin() + .failureHandler(authenticationFailureHandler()) + .successHandler(authenticationSuccessHandler()) + .and() + .exceptionHandling() + .accessDeniedHandler(accessDeniedHandler()) + .and() + .logout(); + } + + @Bean + public AuthenticationFailureHandler authenticationFailureHandler() { + return new CustomAuthenticationFailureHandler(); + } + + @Bean + public AuthenticationSuccessHandler authenticationSuccessHandler() { + return new CustomAuthenticationSuccessHandler(); + } + + @Bean + public AccessDeniedHandler accessDeniedHandler() { + return new CustomAccessDeniedHandler(); + } + +} diff --git a/spring-security-modules/spring-security-core/src/main/resources/application.properties b/spring-security-modules/spring-security-core/src/main/resources/application.properties new file mode 100644 index 0000000000..9d154c9cc0 --- /dev/null +++ b/spring-security-modules/spring-security-core/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.thymeleaf.prefix=classpath:/templates/ \ No newline at end of file diff --git a/spring-security-modules/spring-security-core/src/main/resources/templates/admin.html b/spring-security-modules/spring-security-core/src/main/resources/templates/admin.html new file mode 100644 index 0000000000..d7f7ec232a --- /dev/null +++ b/spring-security-modules/spring-security-core/src/main/resources/templates/admin.html @@ -0,0 +1,5 @@ + + +