-
Notifications
You must be signed in to change notification settings - Fork 2
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
[TLVB-236] 로그인 api 시큐리티 적용 #77
base: develop
Are you sure you want to change the base?
Changes from all commits
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,95 @@ | ||
package kdt.prgrms.kazedon.everevent.configures; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import java.io.IOException; | ||
import java.text.MessageFormat; | ||
import javax.servlet.FilterChain; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import kdt.prgrms.kazedon.everevent.configures.auth.CustomUserDetails; | ||
import kdt.prgrms.kazedon.everevent.domain.user.dto.request.LoginRequest; | ||
import kdt.prgrms.kazedon.everevent.domain.user.dto.response.UserInfoResponse; | ||
import kdt.prgrms.kazedon.everevent.exception.ErrorMessage; | ||
import kdt.prgrms.kazedon.everevent.service.converter.UserConverter; | ||
import lombok.SneakyThrows; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; | ||
import org.springframework.http.server.ServletServerHttpResponse; | ||
import org.springframework.security.authentication.AuthenticationManager; | ||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.core.AuthenticationException; | ||
import org.springframework.security.core.GrantedAuthority; | ||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||
|
||
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter { | ||
|
||
private final AuthenticationManager authenticationManager; | ||
|
||
private final JwtAuthenticationProvider jwtAuthenticationProvider; | ||
|
||
private final UserConverter userConverter; | ||
|
||
public JwtAuthenticationFilter( | ||
AuthenticationManager authenticationManager, | ||
JwtAuthenticationProvider jwtAuthenticationProvider, | ||
UserConverter userConverter) { | ||
this.authenticationManager = authenticationManager; | ||
this.jwtAuthenticationProvider = jwtAuthenticationProvider; | ||
this.userConverter = userConverter; | ||
} | ||
|
||
@SneakyThrows | ||
@Override | ||
public Authentication attemptAuthentication(HttpServletRequest request, | ||
HttpServletResponse response) | ||
throws AuthenticationException { | ||
|
||
LoginRequest loginRequest = new ObjectMapper().readValue(request.getInputStream(), | ||
LoginRequest.class); | ||
|
||
UsernamePasswordAuthenticationToken authenticationToken = | ||
new UsernamePasswordAuthenticationToken( | ||
(loginRequest != null) ? loginRequest.getEmail() : null, | ||
(loginRequest != null) ? loginRequest.getPassword() : null); | ||
|
||
return authenticationManager.authenticate(authenticationToken); | ||
} | ||
|
||
@Override | ||
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, | ||
FilterChain chain, | ||
Authentication authResult) throws IOException { | ||
|
||
CustomUserDetails userDetails = (CustomUserDetails) authResult.getPrincipal(); | ||
String token = jwtAuthenticationProvider.createToken( | ||
userDetails.getUsername(), | ||
userDetails.getAuthorities().stream().map(GrantedAuthority::getAuthority).toList() | ||
); | ||
|
||
response.setHeader("X-AUTH-TOKEN", token); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. JwtProperty 클래스에 변수(HEADER_STRING)로 추가 해도 좋을 것 같슴다ㅏㅏ!! |
||
response.setStatus(HttpStatus.OK.value()); | ||
|
||
UserInfoResponse userInfoResponse = userConverter.convertToUserInfoResponse( | ||
userDetails.getUser()); | ||
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(); | ||
MediaType jsonMimeType = MediaType.APPLICATION_JSON; | ||
|
||
if (jsonConverter.canWrite(userInfoResponse.getClass(), jsonMimeType)) { | ||
jsonConverter.write(userInfoResponse, jsonMimeType, new ServletServerHttpResponse(response)); | ||
} | ||
} | ||
|
||
@Override | ||
protected void unsuccessfulAuthentication(HttpServletRequest request, | ||
HttpServletResponse response, AuthenticationException exception) throws IOException { | ||
LoginRequest loginRequest = new ObjectMapper().readValue(request.getInputStream(), | ||
LoginRequest.class); | ||
|
||
String errorMessage = MessageFormat.format(ErrorMessage.LOGIN_FAILED.getMessage(), | ||
loginRequest.getEmail()); | ||
response.sendError(HttpStatus.UNAUTHORIZED.value(), errorMessage); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,17 +2,21 @@ | |
|
||
import kdt.prgrms.kazedon.everevent.configures.property.JwtProperty; | ||
import kdt.prgrms.kazedon.everevent.service.CustomUserDetailService; | ||
import kdt.prgrms.kazedon.everevent.service.converter.UserConverter; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.http.HttpMethod; | ||
import org.springframework.security.authentication.AuthenticationManager; | ||
import org.springframework.security.config.BeanIds; | ||
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.bcrypt.BCryptPasswordEncoder; | ||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||
import org.springframework.web.filter.CorsFilter; | ||
|
||
@Configuration | ||
|
@@ -23,16 +27,46 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { | |
private final JwtProperty jwtProperty; | ||
private final CustomUserDetailService customUserDetailService; | ||
private final CorsFilter corsFilter; | ||
private final UserConverter userConverter; | ||
|
||
public JwtAuthenticationProvider jwtAuthenticationProvider() { | ||
return new JwtAuthenticationProvider(jwtProperty, customUserDetailService); | ||
} | ||
|
||
@Bean(BeanIds.AUTHENTICATION_MANAGER) | ||
@Override | ||
public AuthenticationManager authenticationManagerBean() throws Exception { | ||
return super.authenticationManagerBean(); | ||
} | ||
|
||
private JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception { | ||
JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter( | ||
authenticationManagerBean(), jwtAuthenticationProvider(), userConverter); | ||
jwtAuthenticationFilter.setFilterProcessesUrl("/api/v1/login"); | ||
return jwtAuthenticationFilter; | ||
} | ||
|
||
@Bean | ||
public BCryptPasswordEncoder passwordEncoder() { | ||
return new BCryptPasswordEncoder(); | ||
} | ||
|
||
@Override | ||
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) | ||
throws Exception { | ||
authenticationManagerBuilder | ||
.userDetailsService(customUserDetailService) | ||
.passwordEncoder(passwordEncoder()); | ||
} | ||
|
||
@Override | ||
public void configure(WebSecurity web) { | ||
web.ignoring().antMatchers( | ||
"/api-docs", | ||
"/webjars/**", | ||
"/h2-console/**"); | ||
Comment on lines
+65
to
+67
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍👍👍 |
||
} | ||
|
||
@Override | ||
protected void configure(HttpSecurity http) throws Exception { | ||
http | ||
|
@@ -42,6 +76,7 @@ protected void configure(HttpSecurity http) throws Exception { | |
.formLogin().disable() | ||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() | ||
.addFilter(new JwtAuthorizationFilter(authenticationManager(), jwtAuthenticationProvider())) | ||
.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) | ||
.authorizeRequests() | ||
.antMatchers("/api/v1/signup") | ||
.anonymous() | ||
|
@@ -77,18 +112,4 @@ protected void configure(HttpSecurity http) throws Exception { | |
.permitAll(); | ||
} | ||
|
||
@Override | ||
public void configure(WebSecurity web) { | ||
web.ignoring().antMatchers( | ||
"/api-docs", | ||
"/webjars/**", | ||
"/h2-console/**"); | ||
} | ||
|
||
@Bean | ||
@Override | ||
public AuthenticationManager authenticationManagerBean() throws Exception { | ||
return super.authenticationManagerBean(); | ||
} | ||
|
||
} |
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.
아래에 예외를 던지는데 이거 사용한 이유가 무엇인가요?