diff --git a/src/main/java/nextstep/app/config/AuthConfig.java b/src/main/java/nextstep/app/config/AuthConfig.java index 1ae6178..9ccda85 100644 --- a/src/main/java/nextstep/app/config/AuthConfig.java +++ b/src/main/java/nextstep/app/config/AuthConfig.java @@ -1,23 +1,27 @@ package nextstep.app.config; import nextstep.security.access.matcher.AnyRequestMatcher; +import nextstep.security.access.matcher.MvcRequestMatcher; import nextstep.security.authentication.AuthenticationManager; import nextstep.security.authentication.BasicAuthenticationFilter; import nextstep.security.authentication.UsernamePasswordAuthenticationFilter; import nextstep.security.authentication.UsernamePasswordAuthenticationProvider; +import nextstep.security.authorization.AuthorizationFilter; +import nextstep.security.config.AuthorizeRequestMatcherRegistry; import nextstep.security.config.DefaultSecurityFilterChain; import nextstep.security.config.FilterChainProxy; import nextstep.security.config.SecurityFilterChain; import nextstep.security.context.HttpSessionSecurityContextRepository; +import nextstep.security.context.SecurityContextHolderFilter; import nextstep.security.context.SecurityContextRepository; import nextstep.security.userdetails.UserDetailsService; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; import org.springframework.web.filter.DelegatingFilterProxy; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import javax.servlet.Filter; -import java.util.ArrayList; import java.util.List; @Configuration @@ -41,9 +45,12 @@ public FilterChainProxy filterChainProxy() { @Bean public SecurityFilterChain securityFilterChain() { - List filters = new ArrayList<>(); - filters.add(new UsernamePasswordAuthenticationFilter(authenticationManager(), securityContextRepository())); - filters.add(new BasicAuthenticationFilter(authenticationManager())); + List filters = List.of( + new SecurityContextHolderFilter(securityContextRepository()), + new UsernamePasswordAuthenticationFilter(authenticationManager(), securityContextRepository()), + new BasicAuthenticationFilter(authenticationManager()), + new AuthorizationFilter() + ); return new DefaultSecurityFilterChain(AnyRequestMatcher.INSTANCE, filters); } @@ -57,4 +64,10 @@ public AuthenticationManager authenticationManager() { return new AuthenticationManager(new UsernamePasswordAuthenticationProvider(userDetailsService)); } + @Bean + public AuthorizeRequestMatcherRegistry authorizeRequestMatcherRegistry() { + return new AuthorizeRequestMatcherRegistry() + .matcher(new MvcRequestMatcher(HttpMethod.GET, "/members")).hasAuthority("ADMIN") + .matcher(new MvcRequestMatcher(HttpMethod.GET, "/members/me")).authenticated(); + } } diff --git a/src/main/java/nextstep/app/ui/LoginController.java b/src/main/java/nextstep/app/ui/LoginController.java index d4660b4..b5ab00d 100644 --- a/src/main/java/nextstep/app/ui/LoginController.java +++ b/src/main/java/nextstep/app/ui/LoginController.java @@ -6,9 +6,9 @@ @RestController public class LoginController { + @PostMapping("/login") public ResponseEntity login() { return ResponseEntity.ok().build(); } - } diff --git a/src/main/java/nextstep/app/ui/MemberController.java b/src/main/java/nextstep/app/ui/MemberController.java index 608cff5..59a1976 100644 --- a/src/main/java/nextstep/app/ui/MemberController.java +++ b/src/main/java/nextstep/app/ui/MemberController.java @@ -2,35 +2,36 @@ import nextstep.app.domain.MemberRepository; import nextstep.app.ui.dto.MemberDto; +import nextstep.security.context.SecurityContextHolder; +import nextstep.security.exception.AuthenticationException; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; -import java.util.stream.Collectors; @RestController public class MemberController { private final MemberRepository memberRepository; - - public MemberController(MemberRepository memberRepository) { + public MemberController(final MemberRepository memberRepository) { this.memberRepository = memberRepository; } @GetMapping("/members") public ResponseEntity> list() { - List members = memberRepository.findAll() - .stream() - .map(member -> new MemberDto( - member.getEmail(), - member.getPassword(), - member.getName(), - member.getImageUrl(), - member.getRoles()) - ) - .collect(Collectors.toList()); - return ResponseEntity.ok(members); + final var members = memberRepository.findAll(); + return ResponseEntity.ok(MemberDto.toList(members)); } + @GetMapping("/members/me") + public ResponseEntity me() { + final var authentication = SecurityContextHolder.getContext().getAuthentication(); + final var email = (String) authentication.getPrincipal(); + + final var member = memberRepository.findByEmail(email) + .orElseThrow(AuthenticationException::new); + + return ResponseEntity.ok(MemberDto.toDto(member)); + } } diff --git a/src/main/java/nextstep/app/ui/dto/MemberDto.java b/src/main/java/nextstep/app/ui/dto/MemberDto.java index 60bb6d4..7518e8e 100644 --- a/src/main/java/nextstep/app/ui/dto/MemberDto.java +++ b/src/main/java/nextstep/app/ui/dto/MemberDto.java @@ -2,8 +2,11 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import nextstep.app.domain.Member; +import java.util.List; import java.util.Set; +import java.util.stream.Collectors; public class MemberDto { @@ -15,10 +18,10 @@ public class MemberDto { @JsonCreator public MemberDto(@JsonProperty("email") final String email, - @JsonProperty("password")final String password, - @JsonProperty("name")final String name, - @JsonProperty("imageUrl")final String imageUrl, - @JsonProperty("roles")final Set roles) { + @JsonProperty("password") final String password, + @JsonProperty("name") final String name, + @JsonProperty("imageUrl") final String imageUrl, + @JsonProperty("roles") final Set roles) { this.email = email; this.password = password; this.name = name; @@ -26,6 +29,22 @@ public MemberDto(@JsonProperty("email") final String email, this.roles = roles; } + public static MemberDto toDto(final Member member) { + return new MemberDto( + member.getEmail(), + member.getPassword(), + member.getName(), + member.getImageUrl(), + member.getRoles() + ); + } + + public static List toList(final List members) { + return members.stream() + .map(MemberDto::toDto) + .collect(Collectors.toList()); + } + public String getEmail() { return email; } diff --git a/src/main/java/nextstep/security/authentication/Authentication.java b/src/main/java/nextstep/security/authentication/Authentication.java index 0298100..2118b43 100644 --- a/src/main/java/nextstep/security/authentication/Authentication.java +++ b/src/main/java/nextstep/security/authentication/Authentication.java @@ -10,4 +10,6 @@ public interface Authentication { Set getAuthorities(); boolean isAuthenticated(); + + boolean isAdmin(); } diff --git a/src/main/java/nextstep/security/authentication/BasicAuthenticationFilter.java b/src/main/java/nextstep/security/authentication/BasicAuthenticationFilter.java index 224c8fc..f7c6d2b 100644 --- a/src/main/java/nextstep/security/authentication/BasicAuthenticationFilter.java +++ b/src/main/java/nextstep/security/authentication/BasicAuthenticationFilter.java @@ -2,7 +2,6 @@ import nextstep.security.context.SecurityContextHolder; import nextstep.security.exception.AuthenticationException; -import nextstep.security.exception.AuthorizationException; import org.springframework.http.HttpStatus; import org.springframework.web.filter.GenericFilterBean; @@ -21,7 +20,7 @@ public class BasicAuthenticationFilter extends GenericFilterBean { private final AuthenticationManager authenticationManager; - public BasicAuthenticationFilter(AuthenticationManager authenticationManager) { + public BasicAuthenticationFilter(final AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } @@ -29,26 +28,19 @@ public BasicAuthenticationFilter(AuthenticationManager authenticationManager) { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try { - Authentication authRequest = convertAuthenticationRequest((HttpServletRequest) request); + final var authRequest = convertAuthenticationRequest((HttpServletRequest) request); if (authRequest == null) { chain.doFilter(request, response); return; } - Authentication authResult = authenticationManager.authenticate(authRequest); + final var authResult = authenticationManager.authenticate(authRequest); SecurityContextHolder.getContext().setAuthentication(authResult); - - if (authResult.getAuthorities().isEmpty()) { - throw new AuthorizationException(); - } } catch (AuthenticationException e) { SecurityContextHolder.clearContext(); ((HttpServletResponse) response).sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase()); return; - } catch (AuthorizationException e) { - ((HttpServletResponse) response).sendError(HttpStatus.FORBIDDEN.value(), HttpStatus.FORBIDDEN.getReasonPhrase()); - return; } chain.doFilter(request, response); @@ -75,6 +67,4 @@ private Authentication convertAuthenticationRequest(HttpServletRequest request) return UsernamePasswordAuthentication.ofRequest(email, password); } - - } diff --git a/src/main/java/nextstep/security/authentication/UsernamePasswordAuthentication.java b/src/main/java/nextstep/security/authentication/UsernamePasswordAuthentication.java index d75f15a..0f01c97 100644 --- a/src/main/java/nextstep/security/authentication/UsernamePasswordAuthentication.java +++ b/src/main/java/nextstep/security/authentication/UsernamePasswordAuthentication.java @@ -47,4 +47,8 @@ public boolean isAuthenticated() { return authenticated; } + public boolean isAdmin() { + return getAuthorities() + .contains("ADMIN"); + } } diff --git a/src/main/java/nextstep/security/authentication/UsernamePasswordAuthenticationFilter.java b/src/main/java/nextstep/security/authentication/UsernamePasswordAuthenticationFilter.java index 1ec7ceb..732b1c1 100644 --- a/src/main/java/nextstep/security/authentication/UsernamePasswordAuthenticationFilter.java +++ b/src/main/java/nextstep/security/authentication/UsernamePasswordAuthenticationFilter.java @@ -1,11 +1,9 @@ package nextstep.security.authentication; import nextstep.security.access.matcher.MvcRequestMatcher; -import nextstep.security.context.SecurityContext; import nextstep.security.context.SecurityContextHolder; import nextstep.security.context.SecurityContextRepository; import nextstep.security.exception.AuthenticationException; -import nextstep.security.exception.AuthorizationException; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.web.filter.GenericFilterBean; @@ -20,21 +18,24 @@ public class UsernamePasswordAuthenticationFilter extends GenericFilterBean { + private static final MvcRequestMatcher DEFAULT_REQUEST_MATCHER = new MvcRequestMatcher(HttpMethod.POST, "/login"); + private final AuthenticationManager authenticationManager; private final SecurityContextRepository securityContextRepository; - private static final MvcRequestMatcher DEFAULT_REQUEST_MATCHER = new MvcRequestMatcher(HttpMethod.POST, - "/login"); - public UsernamePasswordAuthenticationFilter(AuthenticationManager authenticationManager, SecurityContextRepository securityContextRepository) { + public UsernamePasswordAuthenticationFilter(final AuthenticationManager authenticationManager, + final SecurityContextRepository securityContextRepository) { this.authenticationManager = authenticationManager; this.securityContextRepository = securityContextRepository; } @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + public void doFilter(ServletRequest servletRequest, ServletResponse response, FilterChain chain) throws IOException, ServletException { + + final var request = (HttpServletRequest) servletRequest; try { - if (!DEFAULT_REQUEST_MATCHER.matches((HttpServletRequest) request)) { + if (!DEFAULT_REQUEST_MATCHER.matches(request)) { chain.doFilter(request, response); return; } @@ -42,26 +43,19 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha String username = request.getParameter("username"); String password = request.getParameter("password"); - UsernamePasswordAuthentication authRequest = UsernamePasswordAuthentication.ofRequest(username, + final var authRequest = UsernamePasswordAuthentication.ofRequest(username, password); - Authentication authResult = authenticationManager.authenticate(authRequest); + final var authResult = authenticationManager.authenticate(authRequest); - SecurityContext context = SecurityContextHolder.createEmptyContext(); + final var context = SecurityContextHolder.createEmptyContext(); context.setAuthentication(authResult); SecurityContextHolder.setContext(context); - securityContextRepository.saveContext(context, (HttpServletRequest) request, (HttpServletResponse) response); - - if (authResult.getAuthorities().isEmpty()) { - throw new AuthorizationException(); - } + securityContextRepository.saveContext(context, request, (HttpServletResponse) response); } catch (AuthenticationException e) { SecurityContextHolder.clearContext(); ((HttpServletResponse) response).sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase()); return; - } catch (AuthorizationException e) { - ((HttpServletResponse) response).sendError(HttpStatus.FORBIDDEN.value(), HttpStatus.FORBIDDEN.getReasonPhrase()); - return; } chain.doFilter(request, response); diff --git a/src/main/java/nextstep/security/authorization/AuthorizationFilter.java b/src/main/java/nextstep/security/authorization/AuthorizationFilter.java new file mode 100644 index 0000000..2c6eb82 --- /dev/null +++ b/src/main/java/nextstep/security/authorization/AuthorizationFilter.java @@ -0,0 +1,35 @@ +package nextstep.security.authorization; + +import nextstep.security.context.SecurityContextHolder; +import org.springframework.http.HttpStatus; +import org.springframework.web.filter.GenericFilterBean; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class AuthorizationFilter extends GenericFilterBean { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + final var authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null) { + sendError(response, HttpStatus.UNAUTHORIZED); + return; + } + + if (!authentication.isAdmin()) { + sendError(response, HttpStatus.FORBIDDEN); + return; + } + + chain.doFilter(request, response); + } + + private static void sendError(final ServletResponse response, final HttpStatus httpStatus) throws IOException { + ((HttpServletResponse) response).sendError(httpStatus.value(), httpStatus.getReasonPhrase()); + } +} diff --git a/src/main/java/nextstep/security/context/SecurityContextHolderFilter.java b/src/main/java/nextstep/security/context/SecurityContextHolderFilter.java new file mode 100644 index 0000000..55f432a --- /dev/null +++ b/src/main/java/nextstep/security/context/SecurityContextHolderFilter.java @@ -0,0 +1,27 @@ +package nextstep.security.context; + +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Optional; + +public class SecurityContextHolderFilter extends OncePerRequestFilter { + + private final SecurityContextRepository securityContextRepository; + + public SecurityContextHolderFilter(final SecurityContextRepository securityContextRepository) { + this.securityContextRepository = securityContextRepository; + } + + @Override + protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain filterChain) throws ServletException, IOException { + Optional.ofNullable(securityContextRepository.loadContext(request)) + .ifPresent(SecurityContextHolder::setContext); + + filterChain.doFilter(request, response); + } +} diff --git a/src/test/java/nextstep/app/AcceptanceTest.java b/src/test/java/nextstep/app/AcceptanceTest.java index 835597e..8b3c13f 100644 --- a/src/test/java/nextstep/app/AcceptanceTest.java +++ b/src/test/java/nextstep/app/AcceptanceTest.java @@ -1,11 +1,16 @@ package nextstep.app; import io.restassured.RestAssured; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; import org.junit.jupiter.api.BeforeEach; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.http.MediaType; import org.springframework.test.annotation.DirtiesContext; +import java.util.Map; + @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class AcceptanceTest { @@ -16,4 +21,25 @@ public class AcceptanceTest { public void setUp() { RestAssured.port = port; } + + protected ExtractableResponse get(final String path, + final Map cookies) { + return RestAssured.given().log().all() + .cookies(cookies) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .when() + .get(path) + .then().log().all() + .extract(); + } + protected ExtractableResponse post(final String path, + final Map parameters) { + return RestAssured.given().log().all() + .formParams(parameters) + .contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE) + .when() + .post(path) + .then().log().all() + .extract(); + } } diff --git a/src/test/java/nextstep/app/LoginTest.java b/src/test/java/nextstep/app/LoginTest.java index 58dc708..96b09dc 100644 --- a/src/test/java/nextstep/app/LoginTest.java +++ b/src/test/java/nextstep/app/LoginTest.java @@ -1,9 +1,8 @@ package nextstep.app; -import nextstep.security.authentication.Authentication; -import nextstep.security.context.SecurityContextHolder; import nextstep.app.domain.Member; import nextstep.app.infrastructure.InMemoryMemberRepository; +import nextstep.security.context.SecurityContextHolder; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -18,7 +17,7 @@ @SpringBootTest @AutoConfigureMockMvc -public class LoginTest { +class LoginTest { private static final Member TEST_MEMBER = InMemoryMemberRepository.ADMIN_MEMBER; @Autowired @@ -26,23 +25,23 @@ public class LoginTest { @Test void login_success() throws Exception { - ResultActions loginResponse = requestLoginWith(TEST_MEMBER.getEmail(), TEST_MEMBER.getPassword()); + final var loginResponse = requestLoginWith(TEST_MEMBER.getEmail(), TEST_MEMBER.getPassword()); loginResponse.andExpect(status().isOk()); - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + final var authentication = SecurityContextHolder.getContext().getAuthentication(); assertThat(authentication.isAuthenticated()).isTrue(); } @Test void login_fail_with_no_user() throws Exception { - ResultActions response = requestLoginWith("none", "none"); + final var response = requestLoginWith("none", "none"); response.andExpect(status().isUnauthorized()); } @Test void login_fail_with_invalid_password() throws Exception { - ResultActions response = requestLoginWith(TEST_MEMBER.getEmail(), "invalid"); + final var response = requestLoginWith(TEST_MEMBER.getEmail(), "invalid"); response.andExpect(status().isUnauthorized()); } diff --git a/src/test/java/nextstep/app/MemberAcceptanceTest.java b/src/test/java/nextstep/app/MemberAcceptanceTest.java index 13bda3f..ad0c392 100644 --- a/src/test/java/nextstep/app/MemberAcceptanceTest.java +++ b/src/test/java/nextstep/app/MemberAcceptanceTest.java @@ -1,48 +1,43 @@ package nextstep.app; -import io.restassured.RestAssured; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; import nextstep.app.domain.Member; import nextstep.app.infrastructure.InMemoryMemberRepository; import nextstep.app.ui.dto.MemberDto; import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import java.util.HashMap; -import java.util.List; import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; -public class MemberAcceptanceTest extends AcceptanceTest { +class MemberAcceptanceTest extends AcceptanceTest { private static final Member TEST_MEMBER = InMemoryMemberRepository.ADMIN_MEMBER; @Test void get_members_after_form_login() { - Map params = new HashMap<>(); - params.put("username", TEST_MEMBER.getEmail()); - params.put("password", TEST_MEMBER.getPassword()); - - ExtractableResponse loginResponse = RestAssured.given().log().all() - .formParams(params) - .contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE) - .when() - .post("/login") - .then().log().all() - .extract();; - - ExtractableResponse memberResponse = RestAssured.given().log().all() - .cookies(loginResponse.cookies()) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .when() - .get("/members") - .then().log().all() - .extract(); + final var params = Map.of( + "username", TEST_MEMBER.getEmail(), + "password", TEST_MEMBER.getPassword()); + + final var loginResponse = post("/login", params); + final var memberResponse = get("/members", loginResponse.cookies()); assertThat(memberResponse.statusCode()).isEqualTo(HttpStatus.OK.value()); - List members = memberResponse.jsonPath().getList(".", MemberDto.class); + final var members = memberResponse.jsonPath().getList(".", MemberDto.class); assertThat(members).hasSize(2); } + + @Test + void get_me_after_form_login() { + final var params = Map.of( + "username", TEST_MEMBER.getEmail(), + "password", TEST_MEMBER.getPassword()); + + final var loginResponse = post("/login", params); + final var memberResponse = get("/members/me", loginResponse.cookies()); + + assertThat(memberResponse.statusCode()).isEqualTo(HttpStatus.OK.value()); + final var member = memberResponse.jsonPath().getObject(".", MemberDto.class); + assertThat(member.getEmail()).isEqualTo(TEST_MEMBER.getEmail()); + } } diff --git a/src/test/java/nextstep/app/MemberTest.java b/src/test/java/nextstep/app/MemberTest.java index e3df0de..ef47d7a 100644 --- a/src/test/java/nextstep/app/MemberTest.java +++ b/src/test/java/nextstep/app/MemberTest.java @@ -1,10 +1,9 @@ package nextstep.app; -import nextstep.security.authentication.Authentication; -import nextstep.security.authentication.Role; -import nextstep.security.context.SecurityContextHolder; import nextstep.app.domain.Member; import nextstep.app.infrastructure.InMemoryMemberRepository; +import nextstep.security.authentication.Role; +import nextstep.security.context.SecurityContextHolder; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -22,7 +21,7 @@ @SpringBootTest @AutoConfigureMockMvc -public class MemberTest { +class MemberTest { private static final Member TEST_ADMIN_MEMBER = InMemoryMemberRepository.ADMIN_MEMBER; private static final Member TEST_USER_MEMBER = InMemoryMemberRepository.USER_MEMBER; @@ -31,43 +30,43 @@ public class MemberTest { @Test void request_success_with_admin_user() throws Exception { - ResultActions response = requestWithBasicAuth(TEST_ADMIN_MEMBER.getEmail(), TEST_ADMIN_MEMBER.getPassword()); + final var response = requestWithBasicAuth(TEST_ADMIN_MEMBER.getEmail(), TEST_ADMIN_MEMBER.getPassword()); response.andExpect(status().isOk()) .andExpect(MockMvcResultMatchers.jsonPath("$.length()").value(2)); - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + final var authentication = SecurityContextHolder.getContext().getAuthentication(); assertThat(authentication.isAuthenticated()).isTrue(); assertThat(authentication.getAuthorities()).contains(Role.ADMIN.name()); } @Test void request_fail_with_general_user() throws Exception { - ResultActions response = requestWithBasicAuth(TEST_USER_MEMBER.getEmail(), TEST_USER_MEMBER.getPassword()); + final var response = requestWithBasicAuth(TEST_USER_MEMBER.getEmail(), TEST_USER_MEMBER.getPassword()); response.andExpect(status().isForbidden()); - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + final var authentication = SecurityContextHolder.getContext().getAuthentication(); assertThat(authentication.isAuthenticated()).isTrue(); assertThat(authentication.getAuthorities()).isEmpty(); } @Test void request_fail_with_no_user() throws Exception { - ResultActions response = requestWithBasicAuth("none", "none"); + final var response = requestWithBasicAuth("none", "none"); response.andExpect(status().isUnauthorized()); } @Test void request_fail_invalid_password() throws Exception { - ResultActions response = requestWithBasicAuth(TEST_ADMIN_MEMBER.getEmail(), "invalid"); + final var response = requestWithBasicAuth(TEST_ADMIN_MEMBER.getEmail(), "invalid"); response.andExpect(status().isUnauthorized()); } private ResultActions requestWithBasicAuth(String username, String password) throws Exception { - String token = Base64.getEncoder().encodeToString((username + ":" + password).getBytes()); + final var token = Base64.getEncoder().encodeToString((username + ":" + password).getBytes()); return mockMvc.perform(get("/members") .header("Authorization", "Basic " + token) diff --git a/src/test/java/nextstep/security/authentication/BasicAuthenticationFilterTest.java b/src/test/java/nextstep/security/authentication/BasicAuthenticationFilterTest.java index b5b6685..a7c91b0 100644 --- a/src/test/java/nextstep/security/authentication/BasicAuthenticationFilterTest.java +++ b/src/test/java/nextstep/security/authentication/BasicAuthenticationFilterTest.java @@ -6,7 +6,6 @@ import nextstep.security.fixture.MockFilterChain; import nextstep.security.fixture.TestUserDetailsService; import nextstep.security.fixture.TestUserInMemoryRepository; -import nextstep.security.userdetails.UserDetailsService; import org.apache.http.HttpHeaders; import org.apache.http.HttpStatus; import org.junit.jupiter.api.AfterEach; @@ -19,15 +18,15 @@ import static org.assertj.core.api.Assertions.assertThat; -public class BasicAuthenticationFilterTest { +class BasicAuthenticationFilterTest { private static final Member TEST_MEMBER = InMemoryMemberRepository.ADMIN_MEMBER; private BasicAuthenticationFilter filter; @BeforeEach void setUp() { - UserDetailsService userDetailsService = new TestUserDetailsService(new TestUserInMemoryRepository()); - AuthenticationProvider provider = new UsernamePasswordAuthenticationProvider(userDetailsService); - AuthenticationManager authenticationManager = new AuthenticationManager(provider); + final var userDetailsService = new TestUserDetailsService(new TestUserInMemoryRepository()); + final var provider = new UsernamePasswordAuthenticationProvider(userDetailsService); + final var authenticationManager = new AuthenticationManager(provider); filter = new BasicAuthenticationFilter(authenticationManager); } diff --git a/src/test/java/nextstep/security/authentication/FormLoginFilterTest.java b/src/test/java/nextstep/security/authentication/FormLoginFilterTest.java index ec94fd9..a610d64 100644 --- a/src/test/java/nextstep/security/authentication/FormLoginFilterTest.java +++ b/src/test/java/nextstep/security/authentication/FormLoginFilterTest.java @@ -7,7 +7,6 @@ import nextstep.security.fixture.MockFilterChain; import nextstep.security.fixture.TestUserDetailsService; import nextstep.security.fixture.TestUserInMemoryRepository; -import nextstep.security.userdetails.UserDetailsService; import org.apache.http.HttpStatus; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -22,15 +21,15 @@ import static org.assertj.core.api.Assertions.assertThat; -public class FormLoginFilterTest { +class FormLoginFilterTest { private static final Member TEST_MEMBER = InMemoryMemberRepository.ADMIN_MEMBER; private UsernamePasswordAuthenticationFilter filter; @BeforeEach void setUp() { - UserDetailsService userDetailsService = new TestUserDetailsService(new TestUserInMemoryRepository()); - AuthenticationProvider provider = new UsernamePasswordAuthenticationProvider(userDetailsService); - AuthenticationManager authenticationManager = new AuthenticationManager(provider); + final var userDetailsService = new TestUserDetailsService(new TestUserInMemoryRepository()); + final var provider = new UsernamePasswordAuthenticationProvider(userDetailsService); + final var authenticationManager = new AuthenticationManager(provider); filter = new UsernamePasswordAuthenticationFilter(authenticationManager, new HttpSessionSecurityContextRepository()); }