稲妻市場V 2-(2)JWTトークン
6621 ワード
1.SecurityContextPersistentFilter
2.LogoutFilter
3.UsernamePasswordAuthenticationFilter
4.DefaultLoginPageGenerationFilter
5.BasicAuthenticationFilter
6.RememberMeAuthenticationFilter
7.AnonymousAuthenticationFilter
8.SessionManagementFilter
9.ExceptionTranslationFilter
10.FilterSecurityInterceptor
3番目のU s e r m e P a s s s w o r d AuthenticationFilterの前に、jwt関連フィルタを加えてトークンに分け、ユーザーをSecurityContextHolderに入れるか、異常処理を行います.
トークンの作成
ログインに成功したら、コインを提供します.
トークンを生成する方法.トークンは、ユーザのid、emailをclaimに入れ、後で作成するAPIに使用します.
// JWT 토큰 생성
public String createToken(Long userIdx,String email) {
Date now = new Date();
return Jwts.builder()
.claim("userIDx", userIdx)
.claim("email", email)// 정보 저장
.setIssuedAt(now) // 토큰 발행 시간 정보
.setExpiration(new Date(now.getTime() + tokenValidTime)) // set Expire Time
.signWith(SignatureAlgorithm.HS256, secretKey) // 사용할 암호화 알고리즘과 signature 에 들어갈 secret값 세팅
.compact();
}
タグから情報を抽出
以下のpermitAll()で提供されるAPIのほか、トークンも必要です.
会員登録や登録時にはトークンがないため、開く必要がありますが、Mypageのような場合はトークンが必要です.この設定は、次のWebSecurityConfigurator Adapterで変更できます.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().disable()
.csrf().ignoringAntMatchers("/h2-console/**").disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/h2-console/**").permitAll()
.antMatchers("/user/**").permitAll()
.antMatchers("/category/**").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.accessDeniedHandler(accessDeniedHandler)
.and()
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider),
UsernamePasswordAuthenticationFilter.class);
}
Spring Securityは、図のように上のフィルタチェーンでログインします.JWTを使用したログインを処理するには、U s e r m e P a s s s s w o r d AuthenticationFilterの前にJWT処理に関連するフィルタを挿入します.@RequiredArgsConstructor
public class JwtAuthenticationFilter extends GenericFilter {
private final JwtTokenProvider jwtTokenProvider;
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 헤더에서 JWT 를 받아옵니다.
String token = jwtTokenProvider.resolveToken((HttpServletRequest) servletRequest);
// 유효한 토큰인지 확인합니다.
if (token != null && jwtTokenProvider.validateToken(servletRequest,token)) {
try {
// 토큰이 유효하면 토큰으로부터 유저 정보를 받아옵니다.
Authentication authentication = jwtTokenProvider.getAuthentication(token);
// SecurityContext 에 Authentication 객체를 저장합니다.
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (UsernameNotFoundException e) {
servletRequest.setAttribute("exception","UsernameNotFoundException");
}
}
filterChain.doFilter(servletRequest, servletResponse);
}
}
Headerにタグを追加してAPIを呼び出す場合、タグから情報を抽出したり、タグを検証したりする方法が必要になります.前述したように、リーダにX-AUTH-TOCKENを挿入してAPIを呼び出す場合
Headerからトークンを抽出する方法.トークンがない場合やトークンがない場合は例外処理を行います.
Headerからトークンを抽出する方法.トークンがない場合やトークンがない場合は例外処理を行います.
public String resolveToken(HttpServletRequest request) {
String token = request.getHeader("X-AUTH-TOKEN");
if (token == null || token.isEmpty()) {
request.setAttribute("exception","NotFoundToken");
}
return token;
}
コインを確認する必要があります.次のタグが無効な場合は、フィルタで例外処理を行います.(1)トークンなし
(2)フラグが一致しない
(3)トークンの期限切れ
(4)トークン検証後の権限拒否
public boolean validateToken(ServletRequest request, String jwtToken) {
try {
Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwtToken);
return true;
} catch (MalformedJwtException e) {
request.setAttribute("exception","MalformedJwtException");
} catch (ExpiredJwtException e) {
request.setAttribute("exception","ExpiredJwtException");
} catch (UnsupportedJwtException e) {
request.setAttribute("exception","UnsupportedJwtException");
} catch (IllegalArgumentException e) {
request.setAttribute("exception","IllegalArgumentException");
} catch (SignatureException e) {
request.setAttribute("exception", "SignatureException");
}
return false;
}
トークングループに保存されたEメールをUserDetailsServiceに送信し、ユーザーを検索してSecurityContextHolderに送信します.public Authentication getAuthentication(String token) {
UserDetails userDetails = userDetailsService.loadUserByUsername(this.getUserPk(token));
return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
}
public String getUserPk(String token) {
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().get("email", String.class);
}
@RequiredArgsConstructor
@Service
public class CustomUserDetailService implements UserDetailsService {
private final UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
return userRepository.findByEmail(email).orElseThrow(() -> new UsernameNotFoundException("NOT FOUND USER"));
}
}
Reference
この問題について(稲妻市場V 2-(2)JWTトークン), 我々は、より多くの情報をここで見つけました https://velog.io/@tomy807/번개장터V2-2-JWT-토큰テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol