JPA_ 로그인 #2 (스프링 시큐리티 권한/인증 설정)

김지영·2024년 3월 26일

jpa

목록 보기
13/18
post-thumbnail

§ 스프링 시큐리티 권한/인증 설정

◈ 스프링 시큐리티 규칙 정의

: 권한 관리 / 인증 규칙을 정의하는 곳
예) 부서는 일반 유저가 볼수 있음, 갤러리는 관리자만 볼수있음 (권한 관리)

1. 화면 출력

2. @Configuration

: 자바 파일을 스프링의 환경 설정을 할수 있게 하는 어노테이션

3. @Bean

: 자바 설정파일의 함수 위에 붙여서 IOC 를 해주는 어노테이션
(IOC : 스프링을 객체를 생성해주는 기능)

4. 스프링 시큐리티 규칙 정의 함수(★★★)

-WebSecurityConfig.java

① 스프링 시큐리티

: 기본설정이 없으면 모든 요청에 대해 보안모드로 적용됨

→ 로그인화면(기본화면: 스프링 시큐리티 라이브러리에서 제공함)
→ WebSecurityConfig.java filterChain() 에서 인증 설정하면 화면 볼 수 있음

② 인증 설정 부분

  • 인증(authority)
    : 로그인시 적절한 사용자인지 확인하는 절차

  • 인가(authentication)
    : 로그인은 했지만 일정 권한을 가진 사람만 특정 화면을 볼 수 있는 권리, 권한관리라고도 함

1) authorize

: 권한 설정(==인가) (사용자/관리자 권한에 따라 화면을 볼 수 있는 설정)

2) authentication

: 인증(로그인: ID , PassWord)

3) http.authorizeRequests()

  • 사용법
.requestMatchers("url 경로").permitAll();

4) .requestMatchers("/auth/**").permitAll()

: /auth/ 아래 url 만 접근 가능

  • 사용법
.requestMatchers("url 경로").hasRole("ADMIN");  // 관리자만 사용 가능
 .requestMatchers("/**").hasRole("ADMIN") // /ROLE_ADMIN 권한을 가진 자만 접근가능
                .requestMatchers("/**").permitAll(); // 루뜨 뒤에 있는 모든 사용자 접근 권한을 허용
                
return http.build();
    }

5. 인증방식

1) 쿠키/세션 인증 : 전통적인 인증방식으로 주로 JSP 등을 이용하는 프로그램에서 사용하며, 관련 해킹공격이 있으므로 방어에 유의해야함 (csrf 해킹 공격)

  • 쿠키 : 웹브라우저에서 기본적으로 제공하는 저장공간 : 주로 민감 보안외의 정보를 넣어서 관리

  • 세션 : 서버에서 정상적인 유저로 확인되면 세션이라는 공간에 인증 정보를 저장하고 세션ID 를 발급해서 쿠키에 넣어 유저에게 전송함, 유저는 로그인 후 다른 화면을 검색할때 정상적인 유저임을 확인하기 위해 항상 쿠키안의 세션id 를 확인함 (쿠키는 서버로 자동전송됨)

  • 인증절차
    1) 로그인 버튼을 클릭하면 유저/암호 정보를 spring 서버로 전송
    2) spring 서버에서 정상적인 유저인지 DB 에서 확인 : 스프링 시큐리티 인증
    3) 확인되면 세션ID 를 발급해서 쿠키에 넣어 유저의 웹브라우저로 전송
    4) 유저는 이제 세션ID 가 있는 쿠키를 가지고 해당 웹사이트의 화면을 볼수 있음
    => 상기의 모든 절차는 spring security 에서 몇가지 설정에 의해 자동으로 모두 이루어지며 기본으로 작동되어 코딩은 필요없음
    => 단, 쿠키/세션에 대한 csrf 해킹공격이 있으므로 방어를 위해 csrf 토큰인증을 추가로 진행해야함

☆ 인증 방식 : jsp : 쿠키/세션 방식을 사용

  • 쿠키는 웹브라우저에서 자동으로 spring(벡엔드) 으로 전송함
  • spring 인증된 사용자에 대해 쿠키에 세션id를 넣어서 그 사용자에게 전송
  • 그 사용자는 쿠키(세션id)를 사용해서 다른 화면을 볼 수 있음 ( 만약 쿠키에 세션id 없으면 불법 사용자임 , 인증 에러 : 403 )
  • vs JWT(웹토큰) 인증도 있음(vue, react 사용)

6. 인증(로그인/로그아웃) 관리 : 쿠키/세션 방식(스프링시큐리티에서 자동 관리)

1) 로그인 설정

1) 로그인 설정
        http.formLogin()   // 스프링시큐리티에서 제공하는 로그인화면
                .loginPage("/auth/customLogin")  // 기본로그인화면 대신 개발자가 만든 화면 사용 (새 로그인페이지)
                .loginProcessingUrl("/auth/login")
                //  => 로그인 버튼(jsp) 클릭 시 실행될 함수 url (스프링시큐리티가 자동실행함,
                //                                          컨트로러 함수 불필요함,
                //                                          기본정보 : user 객체 정보 제공)
                .defaultSuccessUrl("/");  // 로그인 성공하면 강제 이동할 페이지

7. 로그아웃 설정

2) 로그아웃 설정

        http.logout()
                .logoutUrl("auth/customLogout")  // 로그아웃 진행
                // 로그아웃 처리 진행 : 스피링시큐리티가 자동으로 진행함
//                  아래 url : jsp 에서 클릭시 로그아웃 진행됨 : post 방식(로그인/로그아웃 동일)(숨겨서 백엔드로 전송)
                .invalidateHttpSession(true)  // 세션 ID 무효화 == 세션 ID 제거
                .logoutSuccessUrl("/"); // 로그아웃 성공하면 강제 이동할 페이지

8. 로그인 사용자 클래스

-Member.java

@Entity
@Table(name = "TB_MEMBER")
@DynamicInsert
@DynamicUpdate
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
// soft delete jpa 어노테이션
@Where(clause = "DELETE_YN = 'N'")
@SQLDelete(sql = "UPDATE TB_MEMBER SET DELETE_YN = 'Y', DELETE_TIME=TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') WHERE EMAIL = ?")

public class Member extends BaseTimeEntity2 {
    @Id
    private String email;  // 로그인 id (스프링시큐리티 속성 : username)
    private String password; // 암호
    private String name; // 유저명
    private String code_name; // 권한명: ROLE_USER(사용자), ROLE_ADMIN(관리자)

}

9. 로그인 레포지토리

public interface MemberRepository  extends JpaRepository<Member, String> {

}

10. 로그인 서비스

@Service
public class MemberService {

    @Autowired
    private MemberRepository memberRepository;  // DI

    //    TODO: 로그인 관련 함수
//     상세조회
    public Optional<Member> findById(String email) {
        Optional<Member> optionalMember
                = memberRepository.findById(email);
        return optionalMember;
    }
}

11. 패스워드 암호화 함수 : 필수 정의

- @Bean

: IOC (스프링이 객체를 생성해주는 것), 함수의 리턴객체를 생성함

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

-MemberController

  • DB 서비스 객체
    @Autowired
    MemberService memberService;     // DI

    @Autowired
    PasswordEncoder passwordEncoder; // 암호화 객체 DI
  • 로그인

    1) 로그인 페이지 열기 함수(제작)
    => WebSecurityConfig.java filterChain() 함수안에 정의

    @GetMapping("/customLogin")
    public String login() {
        return "auth/customLogin.jsp";
    }

2) 로그인 버튼 클릭하면 실행될 함수(안만듬, 스프링자동) => jsp : form action="/auth/login"
=> WebSecurityConfig.java filterChain() 함수안에 정의
=> DB에 사용자가 있는지 확인하는 함수 (개발자가 작성)
=> 스프링이 인증할때 그 함수를 자동 실행
=> DB 확인해서 정상사용자인지 검증이 끝나면 --> 검증객체에 넣음(개발자 작성)


-MemberDto

12. 검증된 유저 객체

  • 1) 스프링에서 제공한 유저 클래스 : User, UserDetails 2중에 1개 상속
  • 2) 검증된 유저 객체에는 권한이 있음 : 권한 넣기
@Setter
@Getter
@ToString
public class MemberDto extends User {

    // 개발자 추가 속성(필드) : email
    private String email; // 로그인 ID == username

//    생성자 : 자동생성 : alt + insert(cmd + n)

//    권한이 배열로 되어있다.
    public MemberDto(String email, String password, Collection<? extends GrantedAuthority> authorities) {
        super(email, password, authorities);
        this.email = email;
    }
}

-UserDetailsServiceImpl

13. DB 에 사용자 있는지 확인하는 클래스(함수)

  • 1) 스프링에서 제공한 함수명으로 작성 : 인터페이스 상속(함수명 있음)

① 유저 DB 인증 : 상세조회

  • 사용법
    : 옵셔널객체.orElseThrow(new 예외처리클래스("에러메세지"));
    => 옵셔널객체의 결과가 null 이면 에러메세지 출력, 아니면 변수에 저장됨
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    //    DB Member 레포지토리 DI
    @Autowired
    MemberRepository memberRepository;

    //    함수 재정의 : 자동 기능 : alt + insert
    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
//        TODO: 1) 유저 DB 인증 : 상세조회
//          js 화살표 함수 : function(x){return x+1;} : (x) => x + 1;
//          java 람다식   : interface x(함수())       : (x) -> x + 1;
//          사용법 : 옵셔널객체.orElseThrow(new 예외처리클래스("에러메세지"));
//            => 옵셔널객체의 결과가 null 이면 에러메세지 출력, 아니면 변수에 저장됨
        Member member
                = memberRepository.findById(email)
                .orElseThrow(() -> new UsernameNotFoundException("email 없음:" + email));

        return null;
    }
}

-costomlogin.jsp

14. csrf 보안 토큰 : 해킹 방지 토큰

  • 해킹공격 방지
  • 언제사용?
    : post,put, delete 방식 사용시 넣어주어야 인증됨
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
- 예) 로그인/로그아웃, 부서추가/수정, 사원추가/수정 등

![](https://velog.velcdn.com/images/jy3022/post/8e39788e-e8fd-4ad7-9861-cd2c3bc8e95d/image.png)
profile
그냥 졍이라구하자

0개의 댓글