๐ํ๋ก๊ทธ๋๋จธ์ค ๋ฐฑ์๋ ๋ฐ๋ธ์ฝ์ค 4๊ธฐ ๊ต์ก๊ณผ์ ์ ๋ฃ๊ณ ์ ๋ฆฌํ ๊ธ์
๋๋ค.๐
Jwt ์ ์ฉ Authentication ์ถ๊ฐ
public class JwtAuthenticationToken extends AbstractAuthenticationToken {
private final Object principal;
private String credentials;
public JwtAuthenticationToken(String principal, String credentials) {
super(null);
super.setAuthenticated(false);
this.principal = principal;
this.credentials = credentials;
}
JwtAuthenticationToken(Object principal, String credentials, Collection<? extends GrantedAuthority> authorities) {
super(authorities);
super.setAuthenticated(true);
this.principal = principal;
this.credentials = credentials;
}
}
- ์ง๊ธ๊น์ง Authentication ์ธํฐํ์ด์ค ๊ตฌํ์ฒด๋ก Spring Security์์ ๊ธฐ๋ณธ ์ ๊ณตํ๋ UsernamePasswordAuthenticationToken์ ์ฌ์ฉํจ
- ์ง๊ธ๋ถํฐ JWT ์ธ์ฆ ์ฒ๋ฆฌ๋ผ๋ ๊ฒ์ ๋ช
ํํ ํ๊ธฐ ์ํด Authentication ์ธํฐํ์ด์ค ๊ตฌํ์ฒด๋ก JwtAuthenticationToken ํด๋์ค๋ฅผ ์ถ๊ฐํจ
- ๋์ด์ UsernamePasswordAuthenticationToken ์ฌ์ฉ ์ํจ
public class JwtAuthentication {
public final String token;
public final String username;
JwtAuthentication(String token, String username) {
checkArgument(isNotEmpty(token), "token must be provided.");
checkArgument(isNotEmpty(username), "username must be provided.");
this.token = token;
this.username = username;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
.append("token", token)
.append("username", username)
.toString();
}
}
- ๋ํ, ๊ธฐ์กด UsernamePasswordAuthenticationToken ํด๋์ค์์ ์ธ์ฆ๋ ์ฌ์ฉ์์ principal ํ์
์ผ๋ก org.springframework.security.core.userdetails.User ํ์
์ด ์ฌ์ฉ
- ํ์ง๋ง ์ด์ ๋ถํฐ JwtAuthenticationToken์ ์ฌ์ฉํ๋ฏ๋ก principal ํ์
์ JwtAuthentication ํ์
์ ์ง์ ๋ง๋ค์ด์ ๋ ์๋ง๊ฒ ์ฌ์ฉ
JwtAuthenticationFilter ์์
public class JwtAuthenticationFilter extends GenericFilterBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final String headerKey;
private final Jwt jwt;
public JwtAuthenticationFilter(String headerKey, Jwt jwt) {
this.headerKey = headerKey;
this.jwt = jwt;
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if (SecurityContextHolder.getContext().getAuthentication() == null) {
String token = getToken(request);
if (token != null) {
try {
Jwt.Claims claims = verify(token);
log.debug("Jwt parse result: {}", claims);
String username = claims.username;
List<GrantedAuthority> authorities = getAuthorities(claims);
if (isNotEmpty(username) && authorities.size() > 0) {
JwtAuthenticationToken authentication =
new JwtAuthenticationToken(new JwtAuthentication(token, username), null, authorities);
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
} catch (Exception e) {
log.warn("Jwt processing failed: {}", e.getMessage());
}
}
} else {
log.debug("SecurityContextHolder not populated with security token, as it already contained: '{}'",
SecurityContextHolder.getContext().getAuthentication());
}
chain.doFilter(request, response);
}
private Jwt.Claims verify(String token) {
return jwt.verify(token);
}
private List<GrantedAuthority> getAuthorities(Jwt.Claims claims) {
}
}
- JWT ํ ํฐ์ ๊ฒ์ฆํ๊ณ , ๋์ฝ๋ฉํ ๋ค์ JwtAuthenticationToken ๊ฐ์ฒด๋ฅผ ์์ฑ
- JwtAuthenticationToken ์์ฑ์์ ๋งค๊ฐ๋ณ์
- principal ํ๋: JwtAuthentication ๊ฐ์ฒด
- details ํ๋: ํด๋ผ์ด์ธํธ IP ์ ๋ณด๋ฅผ ์ง๋, WebAuthenticationDetails ๊ฐ์ฒด
- SecurityContextHolder.getContext().setAuthentication ๋ฉ์๋๋ฅผ ํธ์ถํด JwtAuthenticationToken ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ์ ๋ฌํจ