티스토리 뷰

반응형

54, 55 인가1-2

authorization

인가:  사용자에게 (쓰고 읽는) 권한을 줄 수 있다.

 

stateless->  우리는 상태(session)를 관리하지 않는다.   요청을 받을때마다 access token 을 활용해 사용자 식별할 예정 (header)

헤더에는 키와 밸류 쌍으로 여러가지정보를 넣을 수 있는데 이번 강좌에서는    authorization:Bearer 이걸 다룬다.

 

토큰에서 filter 을 추가해 jwt 토큰에서 정보를 추출한다.

BasicAutheneicationFilter :  access token 분석하는데 사용

 

Autheneication Token: spring 제공 객체,어떤 사용자가 사용중인지를 확인 (jwt 를 확인에서 내부적으로 사용할 Autheneication Token 을 만들 예정 (스프링 내부에서만 쓰이고 외부에서 사용 못하는 것))

-> UsernamePasswordAuthenticationToken 이라는 것을 재사용할 예정 (더 복잡하게 하려면 abstract authentication token 을 확장해서 사용하면 됩니다.)

 

 

 


package kr.co.fastcampus.eatgo;

import kr.co.fastcampus.eatgo.filters.JwtAuthenticationFilter;
import kr.co.fastcampus.eatgo.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.servlet.Filter;

@Configuration//
@EnableWebSecurity
public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {

    @Value("${jwt.secret}")
    private String secret;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        Filter filter = new JwtAuthenticationFilter(authenticationManager(), jwtUtil()); //요기요기

        http
                .cors().disable() //http security
                .csrf().disable()//http security
                .formLogin().disable()//http security
                .headers().frameOptions().disable()// HeadersConfigurerer(http security)
                .and() //and 를 활용해서 한번 초기화 (이걸 안하려면 http security쪽에 작성하면된다.)
                .addFilter(filter) // //http security
                .sessionManagement() //  세션에 대한 설정 1
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS); //  세션에 대한 정체 정하기 (따로 세션 관리 안하기)
                
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public JwtUtil jwtUtil() {//
        return new JwtUtil(secret);
    }

}

 

 

package kr.co.fastcampus.eatgo.filters;

import io.jsonwebtoken.Claims;
import kr.co.fastcampus.eatgo.utils.JwtUtil;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
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;

public class JwtAuthenticationFilter extends BasicAuthenticationFilter { //확장한 것을 보고
// 생성자인 것에서 override

    private JwtUtil jwtUtil; //jwtUtil 사용 

    public JwtAuthenticationFilter(
            AuthenticationManager authenticationManager, JwtUtil jwtUtil) {
        super(authenticationManager);
        this.jwtUtil = jwtUtil;// 생성자에 추가
    }
    //TODO: 실제로 JWT 분석 하는 곳

    @Override
    protected void doFilterInternal(
            HttpServletRequest request,
            HttpServletResponse response,
            FilterChain chain
    ) throws IOException, ServletException {
        Authentication authentication = getAuthentication(request);// 헤더에서 데이터 얻기//authentication 갖기
// 에러 핸들링--> 밑으로 
        if (authentication != null) {
            SecurityContext context = SecurityContextHolder.getContext();//실제 사용 context 세팅 
            context.setAuthentication(authentication);
        }

        chain.doFilter(request, response); // 이게 가장 기본 적인것 . 체인을 통해서 request, reponser  연동
    }

    private Authentication getAuthentication(HttpServletRequest request) {// 에러 핸들링 ( 
        String token = request.getHeader("Authorization");
        if (token == null) {
            return null;
        }

        Claims claims = jwtUtil.getClaims(token.substring("Bearer ".length()));//Bearer 제거

        Authentication authentication =
                new UsernamePasswordAuthenticationToken(claims, null); //기본 제공 으로 만들었지만, 직접 만들 수 있다.
        return authentication;
    }
}

 

 

 

package kr.co.fastcampus.eatgo.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;

import java.security.Key;

public class JwtUtil {

    private Key key;

    public JwtUtil(String secret) {
        this.key = Keys.hmacShaKeyFor(secret.getBytes());
    }

    public String createToken(Long userId, String name, Long restaurantId) {
        JwtBuilder builder = Jwts.builder()
                .claim("userId", userId)
                .claim("name", name);
        if (restaurantId != null) {
            builder = builder.claim("restaurantId", restaurantId);
        }
        return builder
                .signWith(key, SignatureAlgorithm.HS256)
                .compact();
    }

    public Claims getClaims(String token) {
        return Jwts.parser()
                .setSigningKey(key)
                .parseClaimsJws(token)//sign이 포함된 jwt 읽는다.
                .getBody();
    }
}
© 2020 GitHub, In

 

 

 

 

 

ackage kr.co.fastcampus.eatgo.interfaces;

import io.jsonwebtoken.Claims;
import kr.co.fastcampus.eatgo.application.ReservationService;
import kr.co.fastcampus.eatgo.domain.Reservation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@CrossOrigin
@RestController
public class ReservationController {

    @Autowired
    private ReservationService reservationService;

    @GetMapping("/reservations")
    public List<Reservation> list(
            Authentication authentication //이런식으로 쓰는 거야. filter 은
    ) {
        Claims claims = (Claims) authentication.getPrincipal();

        Long restaurantId = claims.get("restaurantId", Long.class);

        List<Reservation> reservations =
                reservationService.getReservations(restaurantId);

        return reservations;
    }

}

 

 

 

 

바 인강이 듣고 싶다면 =>https://bit.ly/3ilMbIO

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함