λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
🎨 Projects/μ—λŸ¬λͺ¨μŒ

[μ—λŸ¬λͺ¨μŒ] com.auth0.jwt.exceptions.AlgorithmMismatchException: The provided Algorithm doesn't match the one defined in the JWT's Header

by HelloRabbit 2023. 3. 21.
728x90

μ—λŸ¬ μ„€λͺ…

μžλ°” ν”„λ‘œμ νŠΈμ—μ„œ λ‘œκ·ΈμΈμ„ κ΅¬ν˜„ν•˜κΈ° μœ„ν•΄ μ‹œνλ¦¬ν‹° ν•„ν„°λ₯Ό 톡해 JWT 토큰을 μƒμ„±ν•˜κ³  ν™•μΈν•˜λŠ” κ³Όμ •μ—μ„œ 생긴 μ—λŸ¬

μ—λŸ¬ 메세지

 

JwtAuthenticationFilter.java

@RequiredArgsConstructor
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
	private final AuthenticationManager authenticationManager;
	
	// /login μš”μ²­μ„ ν•˜λ©΄ μ‚¬μš©μž 정보λ₯Ό μΈμ¦ν•˜κΈ° μœ„ν•΄ μ‹€ν–‰λ˜λŠ” ν•¨μˆ˜
	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
			throws AuthenticationException {
		...μ½”λ“œ μƒλž΅...
	}
	
	// attemptAuthentication()μ—μ„œ 인증이 λλ‚˜λ©΄ μ‹€ν–‰λ˜λŠ” ν•¨μˆ˜
	@Override
	protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
			Authentication authResult) throws IOException, ServletException {
		
		PrincipalDetails principalDetails = (PrincipalDetails) authResult.getPrincipal();
		
		String jwtToken = JWT.create()
        				.withSubject(principalDetails.getUsername())
                    			.withExpiresAt(new Date(System.currentTimeMillis() + (JwtProperties.EXPIRATION_TIME)))
                            		.withClaim("id", principalDetails.getUser().getId())
                            		.withClaim("username", principalDetails.getUser().getUsername())
                            		.sign(Algorithm.HMAC256(JwtProperties.SECRET));
		
		response.addHeader(JwtProperties.HEADER_STRING, JwtProperties.TOKEN_PREFIX + jwtToken);
	}
}

 

JwtAuthorizationFilter.java

public class JwtAuthorizationFilter extends BasicAuthenticationFilter {
	
	private UserRepository userRepository;
	
	public JwtAuthorizationFilter(AuthenticationManager authenticationManager, UserRepository userRepository) {
		super(authenticationManager);
		this.userRepository = userRepository;
	}
	
	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		
		String jwtHeader = request.getHeader(JwtProperties.HEADER_STRING);
		
		if(jwtHeader == null || !jwtHeader.startsWith(JwtProperties.TOKEN_PREFIX)) {
			chain.doFilter(request, response);
			return;
		}
		
		String jwtToken = request.getHeader(JwtProperties.HEADER_STRING)
								 .replace(JwtProperties.TOKEN_PREFIX, "");
		
		// μ—λŸ¬κ°€ λ°œμƒν•˜λŠ” μ‹œμ 
		String username = JWT.require(Algorithm.HMAC512(JwtProperties.SECRET))
				   .build()
				   .verify(jwtToken)
				   .getClaim("username").asString();
		
		...μ½”λ“œ μƒλž΅...
	}
}

 

 

ν•΄κ²°

결둠은 맀우 κ°„λ‹¨ν–ˆλ‹€.

 

JWT 토큰을 처음 μƒμ„±ν•˜κ³ (JwtAuthenticationFilter.java) κ²€μ¦ν•˜λŠ”(JwtAuthorizationFilter.java) 두 κ³Όμ •μ—μ„œ JWT 토큰 μ„œλͺ…에 μ ‘κ·Όν•  λ•Œ 같은 μ•Œκ³ λ¦¬μ¦˜μ„ μ΄μš©ν•΄μ•Ό ν•˜λŠ” κ²ƒμ΄μ—ˆλ‹€. 

 

μœ„μ— JwtAuthenticationFilter.java μ½”λ“œλ₯Ό 보면 Algorithm.HMAC512λ₯Ό μ΄μš©ν•΄μ•Ό ν•˜λŠ”λ° μ‹€μˆ˜λ‘œ λ‹€λ₯Έ μ•Œκ³ λ¦¬μ¦˜(Algorithm.HMAC256)을 λΆˆλŸ¬μ™€ 토큰 μ„œλͺ…ν•œ 것을 확인할 수 μžˆλ‹€. κ·Έλž˜μ„œ μ„œλͺ…은 HMAC256으둜 λ˜μ–΄ μžˆλŠ”λ° 토큰 검증 κ³Όμ •μ—μ„œλŠ” HMAC512둜 ν™•μΈν•˜λ‹ˆκΉŒ 잘λͺ»λœ μ•Œκ³ λ¦¬μ¦˜μ„ μΌλ‹€λŠ” μ—λŸ¬κ°€ λ‚˜λŠ” κ²ƒμ΄μ—ˆλ‹€.

 

끝. :)

 

 

 

λŒ“κΈ€