//์คํ๋ง ์ํ๋ฆฌํฐ์์ UsernamePasswordAuthenticationFilter ๊ฐ ์์
// /login ์์ฒญํด์ username,password ์ ์กํ๋ฉด ์ด ํํฐ๊ฐ ๋์์ ํจ, ๊ทผ๋ฐ formlogin์ disableํด๋์ ์ง๊ธ ์๋์ผ๋ก ์๋์ํจ
//๊ทธ๋์ ํํฐ๋ฅผ ์์๋ฐ์ ๋ง๋ค์ด์ฃผ๊ณ securityconfig์ ๋ฑ๋ก์์ผ ์ฃผ๋๊ฒ์
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter{
private final AuthenticationManager authenticationManager;
// Authentication ๊ฐ์ฒด ๋ง๋ค์ด์ ๋ฆฌํด => ์์กด : AuthenticationManager
// ์ธ์ฆ ์์ฒญ์์ ์คํ๋๋ ํจ์ => /login (๋ก๊ทธ์ธ์๋์ ์คํ๋จ)
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
System.out.println("JwtAuthenticationFilter : ์ง์
");
/*
* 1. username,password ๋ฐ์์
* 2. ์ ์์ธ์ง ๋ก๊ทธ์ธ ์๋๋ฅผ ํจ. authenticationManager๋ก ๋ก๊ทธ์ธ ์๋๋ฅผ ํ๋ฉด PrincipalDetailsService๊ฐ ํธ์ถ๋จ
* 3. loadUserByUsername ํจ์ ์คํ๋จ
* 4. PrincipalDetail๋ฅผ ์ธ์
์ ๋ด๊ณ -> ์ธ์
์ ์๋ด์์ฃผ๋ฉด ๊ถํ ๊ด๋ฆฌ๊ฐ ์๋จ
* 5. JWTํ ํฐ์ ๋ง๋ค์ด์ ์๋ต
*/
// request์ ์๋ username๊ณผ password๋ฅผ ํ์ฑํด์ ์๋ฐ Object๋ก ๋ฐ๊ธฐ
ObjectMapper om = new ObjectMapper();
LoginRequestDto loginRequestDto = null;
try {
loginRequestDto = om.readValue(request.getInputStream(), LoginRequestDto.class);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("JwtAuthenticationFilter : "+loginRequestDto);
// ์ ์ ๋ค์ํจ์ค์๋ ํ ํฐ ์์ฑ
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(
loginRequestDto.getUsername(),
loginRequestDto.getPassword());
System.out.println("JwtAuthenticationFilter : ํ ํฐ์์ฑ์๋ฃ");
// authenticate() ํจ์๊ฐ ํธ์ถ ๋๋ฉด ์ธ์ฆ ํ๋ก๋ฐ์ด๋๊ฐ ์ ์ ๋ํ
์ผ ์๋น์ค์
// loadUserByUsername(ํ ํฐ์ ์ฒซ๋ฒ์งธ ํ๋ผ๋ฉํฐ) ๋ฅผ ํธ์ถํ๊ณ
// UserDetails๋ฅผ ๋ฆฌํด๋ฐ์์ ํ ํฐ์ ๋๋ฒ์งธ ํ๋ผ๋ฉํฐ(credential)๊ณผ
// UserDetails(DB๊ฐ)์ getPassword()ํจ์๋ก ๋น๊ตํด์ ๋์ผํ๋ฉด
// Authentication ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ ํํฐ์ฒด์ธ์ผ๋ก ๋ฆฌํดํด์ค๋ค.
// Tip: ์ธ์ฆ ํ๋ก๋ฐ์ด๋์ ๋ํดํธ ์๋น์ค๋ UserDetailsService ํ์
// Tip: ์ธ์ฆ ํ๋ก๋ฐ์ด๋์ ๋ํดํธ ์ํธํ ๋ฐฉ์์ BCryptPasswordEncoder
// ๊ฒฐ๋ก ์ ์ธ์ฆ ํ๋ก๋ฐ์ด๋์๊ฒ ์๋ ค์ค ํ์๊ฐ ์์.
Authentication authentication =
authenticationManager.authenticate(authenticationToken);
PrincipalDetails principalDetailis = (PrincipalDetails) authentication.getPrincipal();
System.out.println("Authentication : "+principalDetailis.getUser().getUsername());
//authentication๊ฐ์ฒด๊ฐ session์์ญ์ ์ ์ฅ์ ํด์ผํ๊ณ ๊ทธ ๋ฐฉ๋ฒ์ด return ํด์ฃผ๋ฉด๋จ
//๊ทธ ์ด์ ๋ ๊ถํ ๊ด๋ฆฌ๋ฅผ ์ํ๋ฆฌํฐ๊ฐ ๋์ ํด์ฃผ๊ธฐ ๋๋ฌธ์ ํธํ๋ ค๊ณ ํ๋๊ฑฐ์
//๊ตณ์ด JWT ํ ํฐ์ ์ฌ์ฉํ๋ฉด์ ์ธ์
์ ๋ง๋ค ์ด์ ๊ฐ ์์ง๋ง ๋จ์ง ๊ถํ์ฒ๋ฆฌ ๋๋ฌธ์ ์ธ์
์ ๋ฃ์ด์ฃผ๋๊ฒ
return authentication;
}
//์์ ํจ์๊ฐ ์คํ์ด ์ข
๋ฃ๋๋ฉด(์ธ์ฆ์ด ์ ์์ผ๋ก ๋๋ฉด) ์ด์ด์ successfulAuthentication๊ฐ ์คํ๋จ
//JWTํ ํฐ์ ๋ง๋ค์ด์ requset์์ฒญํ ์ฌ์ฉ์์๊ฒ JWTํ ํฐ์ reponseํด์ค
// JWT Token ์์ฑํด์ response์ ๋ด์์ฃผ๊ธฐ
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authResult) throws IOException, ServletException {
PrincipalDetails principalDetailis = (PrincipalDetails) authResult.getPrincipal();
//RSA๋ฐฉ์์ ์๋๊ณ Hash์ํธ ๋ฐฉ์
String jwtToken = JWT.create()
.withSubject(principalDetailis.getUsername()) //ํฌ๊ฒ ์ค์ํ์ง ์์
.withExpiresAt(new Date(System.currentTimeMillis()+JwtProperties.EXPIRATION_TIME)) //์ธ์ ๊น์ง ์ ํจํ ์ง ๋ง๋ฃ์๊ฐ
.withClaim("id", principalDetailis.getUser().getId())
.withClaim("username", principalDetailis.getUser().getUsername())
.sign(Algorithm.HMAC512(JwtProperties.SECRET));
response.addHeader(JwtProperties.HEADER_STRING, JwtProperties.TOKEN_PREFIX+jwtToken);
}
}