Authorization Authentication with JWT
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package com.security.jwt.config;
|
||||
|
||||
import com.security.jwt.jwt.JwtAuthenticationFilter;
|
||||
import com.security.jwt.config.jwt.JwtAuthenticationFilter;
|
||||
import com.security.jwt.config.jwt.JwtAuthorizationFilter;
|
||||
import com.security.jwt.repository.UserRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -17,6 +19,7 @@ import org.springframework.web.filter.CorsFilter;
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
private final CorsFilter corsFilter;
|
||||
private final UserRepository userRepository;
|
||||
|
||||
@Bean
|
||||
public BCryptPasswordEncoder passwordEncoder() {
|
||||
@@ -33,6 +36,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
.formLogin().disable()
|
||||
.httpBasic().disable()
|
||||
.addFilter(new JwtAuthenticationFilter(authenticationManager())) // AuthenticationManager
|
||||
.addFilter(new JwtAuthorizationFilter(authenticationManager(), userRepository))
|
||||
.authorizeRequests()
|
||||
.antMatchers("/api/v1/user/**")
|
||||
.access("hasRole('ROLE_USER') or hasRole('ROLE_MANAGER') or hasRole('ROLE_ADMIN')")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.security.jwt.auth;
|
||||
package com.security.jwt.config.auth;
|
||||
|
||||
import com.security.jwt.model.User;
|
||||
import lombok.Data;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.security.jwt.auth;
|
||||
package com.security.jwt.config.auth;
|
||||
|
||||
import com.security.jwt.model.User;
|
||||
import com.security.jwt.repository.UserRepository;
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.security.jwt.jwt;
|
||||
package com.security.jwt.config.jwt;
|
||||
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.security.jwt.auth.PrincipalDetails;
|
||||
import com.security.jwt.config.auth.PrincipalDetails;
|
||||
import com.security.jwt.model.User;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
@@ -84,11 +84,11 @@ public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilte
|
||||
// RSA방식이 아닌 HASH 방식 (secret key 필요 )
|
||||
String jwtToken = JWT.create()
|
||||
.withSubject("wj토큰")
|
||||
.withExpiresAt(new Date(System.currentTimeMillis()+(60000 * 10)))
|
||||
.withExpiresAt(new Date(System.currentTimeMillis()+JwtProperties.EXPIRATION_TIME))
|
||||
.withClaim("id", principalDetails.getUser().getId())
|
||||
.withClaim("username", principalDetails.getUser().getUsername())
|
||||
.sign(Algorithm.HMAC512("wj"));
|
||||
.sign(Algorithm.HMAC512(JwtProperties.SECRET));
|
||||
|
||||
response.addHeader("Authorization", "Bearer " + jwtToken);
|
||||
response.addHeader(JwtProperties.HEADER_STRING, JwtProperties.TOKEN_PREFIX + jwtToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.security.jwt.config.jwt;
|
||||
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.security.jwt.config.auth.PrincipalDetails;
|
||||
import com.security.jwt.model.User;
|
||||
import com.security.jwt.repository.UserRepository;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
// 시큐리티가 가지고 있는 BasicAuthenticationFilter 는
|
||||
// 권한이나 인증이 필요한 특정 주소를 요청 했을 때 필터를 거치게 되고
|
||||
// 만약 권한, 인증이 필요없는 주소면 필터를 거치지 않는다.
|
||||
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 {
|
||||
// super.doFilterInternal(request, response, chain);
|
||||
System.out.println("인증이나 권한이 필요한 주소 요청 : JwtAuthorizationFilter ");
|
||||
|
||||
String jwtHeader = request.getHeader(JwtProperties.HEADER_STRING);
|
||||
System.out.println("jwtHeader " + jwtHeader);
|
||||
|
||||
// jwtHeader가 있는지 확인
|
||||
if(jwtHeader == null || !jwtHeader.startsWith(JwtProperties.TOKEN_PREFIX)) {
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
// jwt token 검증
|
||||
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();
|
||||
// 서명이 정상적으로 완료
|
||||
if(username != null) {
|
||||
User userEntity = userRepository.findByUsername(username);
|
||||
PrincipalDetails principalDetails = new PrincipalDetails(userEntity);
|
||||
// jwt token 서명이 정상이면 Authentication 객체를 만들어 준다.
|
||||
Authentication authentication =
|
||||
new UsernamePasswordAuthenticationToken(principalDetails, null, principalDetails.getAuthorities());
|
||||
|
||||
// 강제로 시큐리티의 세션에 접근하여 Authentication 객체를 저장
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
}
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.security.jwt.config.jwt;
|
||||
|
||||
public interface JwtProperties {
|
||||
String SECRET = "wj";
|
||||
int EXPIRATION_TIME = 60000*10;
|
||||
String TOKEN_PREFIX = "Bearer ";
|
||||
String HEADER_STRING = "Authorization";
|
||||
}
|
||||
@@ -33,4 +33,22 @@ public class RestApiController {
|
||||
userRepository.save(user);
|
||||
return "회원가입완료";
|
||||
}
|
||||
|
||||
// user, manager, admin 접근 가능
|
||||
@GetMapping("/api/v1/user")
|
||||
public String user() {
|
||||
return "user";
|
||||
}
|
||||
|
||||
// manager, admin 접근가능
|
||||
@GetMapping("/api/v1/manager")
|
||||
public String manager() {
|
||||
return "manager";
|
||||
}
|
||||
|
||||
// admin 접근가능
|
||||
@GetMapping("/api/v1/admin")
|
||||
public String admin() {
|
||||
return "admin";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user