Be ready to study forever - 개발자 꿈나무
[Spring Security] JWT적용 본문
1. build.gradle에 dependancies 추가
dependencies{
//...
implementation 'org.springframework.boot:spring-boot-starter-security'//스프링 시큐리티
implementation 'io.jsonwebtoken:jjwt-api:0.10.7'//jjwt
runtime 'io.jsonwebtoken:jjwt-impl:0.10.7'//jjwt
runtime 'io.jsonwebtoken:jjwt-jackson:0.10.7'//jjwt
}
2. JWT를 생성 및 조회할 클래스를 생성한다 추후에 필터나 로그인 후에 발행할 때 사용
public class JwtUtil {
private Key key;
public JwtUtil(String secret){//외부에서(키값음 property.yml에 넣어놈) 시크릿 키 주입
this.key = Keys.hmacShaKeyFor(secret.getBytes());
}
public String createToken(long id, String name) {//JWT생성
String token = Jwts.builder()
.claim("userId",id) //키값과 벨류로 쌍으로 묶임(payload에 들어갈 부분)
.claim("name",name) //키값과 벨류로 쌍으로 묶임(payload에 들어갈 부분)
.signWith(key, SignatureAlgorithm.HS256)//고유한 키값을 해싱
.compact();
return token;
}
public Claims getClamins(String token) {//JWT조회(?)
Claims claims = Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(token)//싸인이 포함된 jwt = jws
.getBody();
return claims;
}
}
3. BasicAuthenticationFilter를 상속받아 JWT를 사용한 필터를 만듬
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {
private JwtUtil jwtUtil;
public JwtAuthenticationFilter(AuthenticationManager authenticationManager, JwtUtil jwtUtil) {//JwtUtil을 사용하기 위해서 생성자로 받음
super(authenticationManager);
this.jwtUtil = jwtUtil;
}
@Override//doFilterInternal은 BasicAuthenticationFilter를 override함
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain chain
) throws IOException, ServletException {
Authentication authentication = getAuthentication(request);
if(authentication != null){
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(authentication);
}
chain.doFilter(request, response);// 체인을 통해 다음작업으로 계속 연결됨
}
private Authentication getAuthentication(HttpServletRequest request){
String token = request.getHeader("Authorization");//header안에 있는 Authentication 값은 없을수도 있기 때문에 예외처리가 필요함
if(token == null){
return null;
}
//header는 Authorization :Bearer fsdgssdgsdgsd32f3.3f233r32r53....
//와 같이 되어 있기 때문에 Bearerㄹ르 서브스트링으로 제거해주고 넘겨야한다
Claims claims = jwtUtil.getClamins(token.substring("Bearer ".length()));
Authentication authentication = new UsernamePasswordAuthenticationToken(claims, null);
return authentication;
}
}
4.시큐리티 설정에 JWT를 이용한 필터를 추가 addFilter(filter)부분
@Configuration//설정 자바파일에는 이 어노테이션을 붙어야함
@EnableWebSecurity//웹 시큐리티를 사용 가능하게 설정합
public class SecurityJavaConfig extends WebSecurityConfigurerAdapter{//자바기반 설정으로 Spring Security를 사용할 수 있다 WebSecurityConfigurerAdapter를상속받아 빠르게 설정이 가능하다
@Value("${jwt.secret}")//깃허브등에 올릴때 외부에 들어나지 않도록 properties.yml에서 가져옴
private String secret;
@Override
protected void configure(HttpSecurity http) throws Exception {
Filter filter = new JwtAuthenticationFilter(authenticationManager(),jwtUtil());//BasicAuthenticationFilter을 상속받음
http.formLogin().disable()//디폴트 로그인 폼을 없앰
.csrf().disable() //csrf인증 기능을 끔
.cors().disable() //cors기능을 끔
.headers().frameOptions().disable()//iframe 차단기능을 끔
.and() //and는 .header에서 http로 나오기 위해 사용
.addFilter(filter)//필터만들어서 적용
.sessionManagement()//세션관리 설정
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);//서버에 값을 세션값을 저장하지 않고 stateless로 설정함
}
@Bean//BCryptPasswordEncoder빈 등록
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean//JwtUtil 빈 등록
public JwtUtil jwtUtil(){
return new JwtUtil(secret);
}
}
properties.yml에 적용도니 jwt의 ket값 @value("$jwt.secret")으로 찾아옴
jwt:
secret: goodlekkfekfosd@424fe4oj5ojofjsdifjhij3lkfjl3jlkrjldk1252f
5.JWT토큰을 에서 이름값 가져오기
@RestController
public class ReviewController {
@Autowired
ReviewService reviewService;
@PostMapping("restaurant/{RestaurantId}/reviews")//Authentication을 필터를 만들어주었기 때문에 가능
public ResponseEntity<Object> create(Authentication authentication, @PathVariable Long RestaurantId, @Valid @RequestBody Review resource) throws URISyntaxException {
Claims claims = (Claims) authentication.getPrincipal();//Claims로 형변환
String name = claims.get("name",String.class);//반환받을 타입을 String.class로 설정
Integer score = resource.getScore();
String description = resource.getDescription();
Review review = reviewService.addReview(RestaurantId,name, description, score);
URI location = new URI("/restaurant/"+RestaurantId+"/reviews/"+review.getId());
return ResponseEntity.created(location).body("{}");
}
}
더 공부가 필요한 부분....
https://webfirewood.tistory.com/m/115?category=694472
'Programming > Spring' 카테고리의 다른 글
Maven (0) | 2020.07.20 |
---|
Comments