diff --git a/2020-05/spring-22/pom.xml b/2020-05/spring-22/pom.xml new file mode 100644 index 00000000..297a78fa --- /dev/null +++ b/2020-05/spring-22/pom.xml @@ -0,0 +1,61 @@ + + + 4.0.0 + + ru.otus + spring-framework-22-auth + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 2.3.3.RELEASE + + + + UTF-8 + UTF-8 + 1.8 + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + + org.springframework.boot + spring-boot-starter-security + + + + + org.springframework.boot + spring-boot-starter-test + + + + org.springframework.security + spring-security-test + ${spring-security.version} + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/2020-05/spring-22/src/main/java/ru/otus/spring/Main.java b/2020-05/spring-22/src/main/java/ru/otus/spring/Main.java new file mode 100644 index 00000000..5406a277 --- /dev/null +++ b/2020-05/spring-22/src/main/java/ru/otus/spring/Main.java @@ -0,0 +1,12 @@ +package ru.otus.spring; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Main { + + public static void main(String[] args) { + SpringApplication.run(Main.class); + } +} diff --git a/2020-05/spring-22/src/main/java/ru/otus/spring/rest/PagesController.java b/2020-05/spring-22/src/main/java/ru/otus/spring/rest/PagesController.java new file mode 100644 index 00000000..18ded522 --- /dev/null +++ b/2020-05/spring-22/src/main/java/ru/otus/spring/rest/PagesController.java @@ -0,0 +1,44 @@ +package ru.otus.spring.rest; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class PagesController { + + @GetMapping("/") + public String indexPage() { + return "index"; + } + + @GetMapping("/public") + public String publicPage() { + SecurityContext securityContext = SecurityContextHolder.getContext(); + Authentication authentication = securityContext.getAuthentication(); + System.out.println(authentication.getPrincipal()); + return "public"; + } + + @GetMapping("/authenticated") + public String authenticatedPage() { + SecurityContext securityContext = SecurityContextHolder.getContext(); + Authentication authentication = securityContext.getAuthentication(); + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + System.out.println(userDetails.getUsername()); + return "authenticated"; + } + + @GetMapping("/success") + public String successPage() { + return "success"; + } + + @GetMapping("/error") + public String errorPage() { + return "error"; + } +} diff --git a/2020-05/spring-22/src/main/java/ru/otus/spring/security/AnonimusUD.java b/2020-05/spring-22/src/main/java/ru/otus/spring/security/AnonimusUD.java new file mode 100644 index 00000000..b7a31238 --- /dev/null +++ b/2020-05/spring-22/src/main/java/ru/otus/spring/security/AnonimusUD.java @@ -0,0 +1,43 @@ +package ru.otus.spring.security; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; + +public class AnonimusUD implements UserDetails { + @Override + public Collection getAuthorities() { + return null; + } + + @Override + public String getPassword() { + return null; + } + + @Override + public String getUsername() { + return "anonymous"; + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } +} diff --git a/2020-05/spring-22/src/main/java/ru/otus/spring/security/SecurityConfiguration.java b/2020-05/spring-22/src/main/java/ru/otus/spring/security/SecurityConfiguration.java new file mode 100644 index 00000000..c40c6950 --- /dev/null +++ b/2020-05/spring-22/src/main/java/ru/otus/spring/security/SecurityConfiguration.java @@ -0,0 +1,59 @@ +package ru.otus.spring.security; + +import org.springframework.beans.factory.annotation.Autowired; +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.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.password.NoOpPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@EnableWebSecurity +public class SecurityConfiguration extends WebSecurityConfigurerAdapter { + + @Override + public void configure( WebSecurity web ) { + web.ignoring().antMatchers( "/" ); + } + + @Override + public void configure( HttpSecurity http ) throws Exception { + http.csrf().disable() + // По умолчанию SecurityContext хранится в сессии + // Это необходимо, чтобы он нигде не хранился + // и данные приходили каждый раз с запросом + .sessionManagement().sessionCreationPolicy( SessionCreationPolicy.STATELESS ) + .and() + .authorizeRequests().antMatchers( "/public" ).anonymous() + .and() + .authorizeRequests().antMatchers( "/authenticated", "/success" ).authenticated() + .and().anonymous().authorities( "ROLE_ANONYMOUS" ).principal( "ya" ) + .and() + // Включает Form-based аутентификацию +// + .formLogin() + +// .and().rememberMe() + + ; +// http.rememberMe() +// .key( "MyDirtySecret" ) +// .tokenValiditySeconds( 50000 ) +// ; + } + + @SuppressWarnings("deprecation") + @Bean + public PasswordEncoder passwordEncoder() { + return NoOpPasswordEncoder.getInstance(); + } + + @Autowired + public void configure( AuthenticationManagerBuilder auth ) throws Exception { + auth.inMemoryAuthentication() + .withUser( "admin" ).password( "password" ).roles( "ADMIN" ); + } +} diff --git a/2020-05/spring-22/src/main/java/ru/otus/spring/security/filter/MyOwnFilter.java b/2020-05/spring-22/src/main/java/ru/otus/spring/security/filter/MyOwnFilter.java new file mode 100644 index 00000000..010afbaa --- /dev/null +++ b/2020-05/spring-22/src/main/java/ru/otus/spring/security/filter/MyOwnFilter.java @@ -0,0 +1,17 @@ +package ru.otus.spring.security.filter; + +import org.springframework.web.filter.GenericFilterBean; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import java.io.IOException; + +public class MyOwnFilter extends GenericFilterBean { + @Override + public void doFilter( ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain ) throws IOException, ServletException { + servletRequest.getParameterMap().put( "SpecialValue", new String[]{ "My dirty secret" } ); + filterChain.doFilter( servletRequest, servletResponse ); + } +} diff --git a/2020-05/spring-22/src/main/resources/templates/authenticated.html b/2020-05/spring-22/src/main/resources/templates/authenticated.html new file mode 100644 index 00000000..0d2043f0 --- /dev/null +++ b/2020-05/spring-22/src/main/resources/templates/authenticated.html @@ -0,0 +1,10 @@ + + + + + Только для авторизованных + + +Только для авторизованных + + diff --git a/2020-05/spring-22/src/main/resources/templates/error.html b/2020-05/spring-22/src/main/resources/templates/error.html new file mode 100644 index 00000000..ba4e50a2 --- /dev/null +++ b/2020-05/spring-22/src/main/resources/templates/error.html @@ -0,0 +1,10 @@ + + + + + Упс... + + +Что-то пошло не так. Печалька + + diff --git a/2020-05/spring-22/src/main/resources/templates/index.html b/2020-05/spring-22/src/main/resources/templates/index.html new file mode 100644 index 00000000..f2d1d1ae --- /dev/null +++ b/2020-05/spring-22/src/main/resources/templates/index.html @@ -0,0 +1,12 @@ + + + + + Главная страница + + +/public +
+/authenticated + + diff --git a/2020-05/spring-22/src/main/resources/templates/public.html b/2020-05/spring-22/src/main/resources/templates/public.html new file mode 100644 index 00000000..b9f93817 --- /dev/null +++ b/2020-05/spring-22/src/main/resources/templates/public.html @@ -0,0 +1,10 @@ + + + + + Доступен всем + + +Доступен всем + + diff --git a/2020-05/spring-22/src/main/resources/templates/success.html b/2020-05/spring-22/src/main/resources/templates/success.html new file mode 100644 index 00000000..58414c01 --- /dev/null +++ b/2020-05/spring-22/src/main/resources/templates/success.html @@ -0,0 +1,10 @@ + + + + + Вы успешно вошли ! + + +Вы успешно вошли ! + + diff --git a/2020-05/spring-22/src/test/java/ru/otus/spring/rest/PagesControllerTest.java b/2020-05/spring-22/src/test/java/ru/otus/spring/rest/PagesControllerTest.java new file mode 100644 index 00000000..13a4e4f1 --- /dev/null +++ b/2020-05/spring-22/src/test/java/ru/otus/spring/rest/PagesControllerTest.java @@ -0,0 +1,30 @@ +package ru.otus.spring.rest; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@WebMvcTest(PagesController.class) +public class PagesControllerTest { + + @Autowired + private MockMvc mockMvc; + + @WithMockUser( + username = "admin", + authorities = {"ROLE_ADMIN"} + ) + @Test + public void testAuthenticatedOnAdmin() throws Exception { + mockMvc.perform(get("/authenticated")) + .andExpect(status().isOk()); + } +}