-
Notifications
You must be signed in to change notification settings - Fork 73
7주차 : 보안 #86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: tmxhsk99
Are you sure you want to change the base?
7주차 : 보안 #86
Changes from 10 commits
6290b43
d0243f6
e3d1669
0974cbf
f92be3b
ac873fb
efd50a3
a3750b6
6178cae
6bb268a
4cce0b9
79bc305
7e94f4b
58215a5
3a54892
9c49112
cbdcc48
1beee7a
887bfb2
9c3aa22
90903bb
3576adf
1c516dd
d1a71ee
b6eb6eb
e1d9b4d
bf63a41
29f2d12
17b2f05
5cb56c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| package com.codesoom.assignment.config; | ||
|
|
||
| import com.codesoom.assignment.filters.AuthenticationErrorFilter; | ||
| import com.codesoom.assignment.filters.JwtAuthenticationFilter; | ||
| import com.codesoom.assignment.utils.JwtUtil; | ||
| import org.springframework.context.annotation.Configuration; | ||
| import org.springframework.http.HttpStatus; | ||
| 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.configuration.WebSecurityConfigurerAdapter; | ||
| import org.springframework.security.config.http.SessionCreationPolicy; | ||
| import org.springframework.security.web.authentication.HttpStatusEntryPoint; | ||
|
|
||
| import javax.servlet.Filter; | ||
| import javax.servlet.http.HttpServletRequest; | ||
|
|
||
| @Configuration | ||
| @EnableGlobalMethodSecurity(prePostEnabled = true) | ||
| public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { | ||
| private final JwtUtil jwtUtil; | ||
| public SecurityJavaConfig(JwtUtil jwtUtil) { | ||
| this.jwtUtil = jwtUtil; | ||
| } | ||
|
|
||
|
|
||
| @Override | ||
| protected void configure(HttpSecurity http) throws Exception { | ||
| Filter authenticationFilter = new JwtAuthenticationFilter(authenticationManager(), jwtUtil); | ||
| Filter authenticationErrorFilter = new AuthenticationErrorFilter(); | ||
|
|
||
| configureAuthorizations(http); | ||
|
|
||
| http | ||
| .csrf().disable() | ||
| .addFilter(authenticationFilter) | ||
| .addFilterBefore(authenticationErrorFilter, | ||
| JwtAuthenticationFilter.class) | ||
| .sessionManagement() | ||
| .sessionCreationPolicy(SessionCreationPolicy.STATELESS) | ||
|
||
| .and() | ||
| .exceptionHandling() | ||
| .authenticationEntryPoint( | ||
| new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)); | ||
| } | ||
|
|
||
| private void configureAuthorizations(HttpSecurity http) throws Exception { | ||
| http.authorizeRequests() | ||
| .requestMatchers(this::matchesPostProductRequest).authenticated() | ||
| .and() | ||
| .authorizeRequests() | ||
| .requestMatchers(this::matchesPatchProductRequest).authenticated() | ||
| .and() | ||
| .authorizeRequests() | ||
| .requestMatchers(this::matchesDeleteProductRequest).authenticated() | ||
| .and() | ||
| .authorizeRequests() | ||
| .requestMatchers(this::matchesPostUserRequest).authenticated() | ||
| .and() | ||
| .authorizeRequests() | ||
| .requestMatchers(this::matchesDeleteUserRequest).authenticated(); | ||
| } | ||
| /** | ||
| * POST /products or /products/{상품아이디} 요청에 대해서만 인증을 요구합니다. | ||
|
||
| * @param req | ||
| * @return | ||
| */ | ||
| private boolean matchesPostProductRequest(HttpServletRequest req) { | ||
| return req.getMethod().equals("POST") && | ||
| (req.getRequestURI().matches("^/products$") || | ||
| req.getRequestURI().matches("^/products/[0-9]+$")); | ||
| } | ||
|
|
||
| /** | ||
| * PATCH /products or /products/{상품아이디} 요청에 대해서만 인증을 요구합니다. | ||
| * @param req | ||
| * @return | ||
| */ | ||
| private boolean matchesPatchProductRequest(HttpServletRequest req) { | ||
| return req.getMethod().equals("PATCH") && | ||
| req.getRequestURI().matches("^/products/[0-9]+$"); | ||
| } | ||
|
|
||
| /** | ||
| * DELETE /products or /products/{상품아이디} 요청에 대해서만 인증을 요구합니다. | ||
| * @param req | ||
| * @return | ||
| */ | ||
| private boolean matchesDeleteProductRequest(HttpServletRequest req) { | ||
| return req.getMethod().equals("DELETE") && | ||
| req.getRequestURI().matches("^/products/[0-9]+$"); | ||
| } | ||
|
|
||
| /** | ||
| * POST /users/{유저아이디} 요청에 대해서만 인증을 요구합니다. | ||
| * @param req | ||
| * @return | ||
| */ | ||
| private boolean matchesPostUserRequest(HttpServletRequest req) { | ||
| return req.getMethod().equals("POST") && req.getRequestURI().matches("^/users/[0-9]+$"); | ||
| } | ||
|
|
||
| /** | ||
| * DELETE /users/{유저아이디} 요청에 대해서만 인증을 요구합니다. | ||
| * @param req | ||
| * @return | ||
| */ | ||
| private boolean matchesDeleteUserRequest(HttpServletRequest req) { | ||
| return req.getMethod().equals("DELETE") && req.getRequestURI().matches("^/users/[0-9]+$"); | ||
| } | ||
| } | ||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| package com.codesoom.assignment.filters; | ||
|
|
||
| import com.codesoom.assignment.errors.InvalidTokenException; | ||
| import org.springframework.http.HttpStatus; | ||
|
|
||
| import javax.servlet.FilterChain; | ||
| import javax.servlet.ServletException; | ||
| import javax.servlet.http.HttpFilter; | ||
| import javax.servlet.http.HttpServletRequest; | ||
| import javax.servlet.http.HttpServletResponse; | ||
| import java.io.IOException; | ||
|
|
||
| public class AuthenticationErrorFilter extends HttpFilter { | ||
| @Override | ||
| protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { | ||
| try { | ||
| chain.doFilter(request,response); | ||
| }catch (InvalidTokenException e){ | ||
| response.sendError(HttpStatus.UNAUTHORIZED.value()); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| package com.codesoom.assignment.filters; | ||
|
|
||
| import com.codesoom.assignment.errors.InvalidTokenException; | ||
| import com.codesoom.assignment.security.UserAuthentication; | ||
| import com.codesoom.assignment.utils.JwtUtil; | ||
| import io.jsonwebtoken.Claims; | ||
| import org.springframework.security.authentication.AuthenticationManager; | ||
| import org.springframework.security.core.Authentication; | ||
| import org.springframework.security.core.context.SecurityContext; | ||
| import org.springframework.security.core.context.SecurityContextHolder; | ||
| import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; | ||
|
|
||
| import javax.servlet.FilterChain; | ||
| import javax.servlet.ServletException; | ||
| import javax.servlet.http.HttpServletRequest; | ||
| import javax.servlet.http.HttpServletResponse; | ||
| import java.io.IOException; | ||
|
|
||
| public class JwtAuthenticationFilter extends BasicAuthenticationFilter { | ||
| private JwtUtil jwtUtil; | ||
|
|
||
| public JwtAuthenticationFilter(AuthenticationManager authenticationManager, JwtUtil jwtUtil) { | ||
| super(authenticationManager); | ||
| this.jwtUtil = jwtUtil; | ||
| } | ||
|
|
||
| @Override | ||
| protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { | ||
|
|
||
| String authorization = request.getHeader("Authorization"); | ||
|
|
||
| if (authorization != null) { | ||
| String accessToken = authorization.substring("Bearer ".length()); | ||
| Claims claims = jwtUtil.decode(accessToken); | ||
|
|
||
| if(claims == null){ | ||
| throw new InvalidTokenException(accessToken); | ||
| } | ||
|
|
||
| Long userId = claims.get("userId", Long.class); | ||
| Authentication authentication = new UserAuthentication(userId); | ||
|
|
||
|
|
||
| SecurityContext context = SecurityContextHolder.getContext(); | ||
| context.setAuthentication(authentication); | ||
| } | ||
|
|
||
| chain.doFilter(request, response); | ||
|
|
||
| } | ||
|
|
||
| } |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여기서 csrf는 왜 disable하는지 이번 기회에 알아보면 좋습니다