Developer Note/국비과정 수업내용 정리&저장

24년 11월 20일

DH_PARK 2024. 11. 25. 03:20

ㅎㅇㅎㅇ

스프링 시큐리티의 보안 객체들

		//예외처리
		http.exceptionHandling()
			.authenticationEntryPoint(new CustomAuthenticationEntryPoint())		//미인증 사용자 예외처리
			.accessDeniedHandler(new CustomAccessDeniedHandler());				//권한 실패(부족)시 예외처리

스프링 시큐리티 예외처리

public class CustomAccessDeniedHandler implements AccessDeniedHandler {

	@Override
	public void handle(HttpServletRequest request, HttpServletResponse response,
			AccessDeniedException accessDeniedException) throws IOException, ServletException {
		
		System.out.println("CustomAccessDeinedHandler 뭐뭐무머 : " +accessDeniedException);
		request.setAttribute("error", accessDeniedException);
		request.getRequestDispatcher("/WEB-INF/views/error.jsp").forward(request, response);
	}

}

사용자 권한 이상의 권한에 접근하려고 하면 예외처리를 한다

public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {		//인증을 받지않은 사용자가 해당 시스템에 접근하려 할때 메시지를 띄움

	@Override
	public void commence(HttpServletRequest request, HttpServletResponse response,
			AuthenticationException authException) throws IOException, ServletException {
		// TODO Auto-generated method stub
		System.out.println("CustomAuthenticationEntryPoint's commence()./.. !1dasdsad" + authException);
		request.setAttribute("message", "인증이 필요한 페이지임 ! ");
		request.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(request, response);	//메시지를 띄우고 로그인 페이지로 포워딩처리함
	}

}

인증 안받은 사용자가 접근하려고 하면 예외처리


		//권한체크
		http.authorizeRequests()
			.antMatchers("/","/join").permitAll()
			.antMatchers("/user").hasRole("USER")
			.antMatchers("/member").hasRole("MEMBER")
			.antMatchers("/admin").hasRole("ADMIN")
			.anyRequest().authenticated();
		
		//로그인
		http.formLogin()
			.loginPage("/login")
			.permitAll()
			.successHandler(new CustomLoginSucccessHandler())	//로그인이 성공했을 때의 핸들러	  //이런건 직접 정의하는 객체인듯 ?
			.failureHandler(new CustomAuthenticationFailureHandler());	//로그인 실패시 처리
		
		
		//로그아웃
		http.logout()
			.permitAll()
			.addLogoutHandler(new CustomLogoutHandler())   //로그아웃을 할 때 핸들러
			.logoutSuccessHandler(new CustomLogoutSuccessHandler());  //로그아웃 성공시의 핸들러
			
			
		
		//예외처리
		http.exceptionHandling()
			.authenticationEntryPoint(new CustomAuthenticationEntryPoint())		//미인증 사용자 예외처리
			.accessDeniedHandler(new CustomAccessDeniedHandler());				//권한 실패(부족)시 예외처리 , 더 높은 권한으로 접근하려 할 때 예외처리
		
		
		//REMEMBER_ME
			
	}

Remember Me 란

원래 페이지를 종료하면 세션이 같이 날아가게 되는데

서버에서 토큰값을 기억해 로그인상태를 유지할 수 있게 해준다.

이 remember me는 세션값이 있는것을 기본전제로 한다.

동작 순서

<div>
			<input type="checkbox" name="remember-me" id="remember-me">
			<label>로그인 상태 유지</label>
		</div>

체크박스에 체크를 한다면 remember-me 가 동작

사용자가 들고온 토큰과 서버에 저장된 토큰이 서로 일치하는지 판단한다.

토큰에 저장된 정보를 DB 에 해당 User 계정이 존재하는지 판단한다.

위 조건을 모두 통과하면 새로운 인증객체 Authentication 를 생성 후에

AuthenticationManager 에게 인증처리를 넘긴다.

이후 response 될 때 JSESSIONID를 다시 보내준다.

Remember me 에는 토큰 방식과 DB 방식이 있다고 한다.

DB 방식의 경우 테이블을 생성하여 로그인시에 해당 테이블 관련 정보 저장 후,

세션이 만료됐을 때 , remember me 가 사용 설정이 되어있을 때 테이블의 정보와 쿠키 정보를 비교하여 자동으로 로그인을 시켜준다.

수업에서는 mysql DB 를 사용하는 DB 방식을 사용했다.

토큰 DB 를 생성하기 위해 PersistentTokenRepository 인터페이스를 구현했다.

JdbcTokenRepositoryImpl 객체를 생성.

그 전에 DB 에서 토큰 테이블을 만든다.

JdbcTokenRepositoryImpl 객체에 자세히 들어가보면

	public static final String CREATE_TABLE_SQL = "create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, "
			+ "token varchar(64) not null, last_used timestamp not null)";

이런 테이블 생성 쿼리문이 있는데 지울 건 지워주고 mysql 에서 쿼리문만 뽑아서 테이블을 생성해준다.

mysql 에서

create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, token varchar(64) not null, last_used timestamp not null);

으로 토큰값을 저장할 테이블 생성

 

 

로그인 상태 유지 체크 후에 로그인을 하면

mysql 토큰 테이블에 토큰 값이 생긴다.

그리고 톰캣을 끈 후에 다시 새로고침해도 토큰 테이블에 토큰 정보값이 남아있기 때문에

로그인 페이지로 돌아가지 않고 그대로 정보가 남아있다 !

신기함. !!

		//REMEMBER_ME
		http.rememberMe()
			.key("rememberMeKey") //사용자 키 값
			.rememberMeParameter("remember-me")	//파라미터 값	
			.alwaysRemember(false)  //항상 리멤버미 기능을 사용할지 여부
			.tokenValiditySeconds(60*60)  //리멤버미 기능 유지시간
			.tokenRepository(tokenRepository());	//토큰 저장소를 설정
	}
@Bean
	public PersistentTokenRepository tokenRepository() {
		JdbcTokenRepositoryImpl repo = new JdbcTokenRepositoryImpl(); //이 클래스에 들어가면 persistent 테이블 만드는 쿼리문이 있다.
		repo.setDataSource(dataSource);
		return repo;
	}

스프링 셋업 , 시큐리티 셋업 연습해야할줄 알아야함.

스프링 시큐리티 기본 셋업 순서 정리

  1. 각종 의존성 추가받기
    1. Spring security 세트 4개(core , web , config , taglibs)
    2. validator
    3. mysql connector-j
    4. mybatis
    5. hikariCP
  2. config 설정 파일 만들기
    1. @EnableWebSecurity 어노테이션을 붙일 시에 시큐리티 설정 파일로 만들겠다는 뜻 , @Configuration 추가
    2. WebSecurityConfigurerAdapter 상속받기
    3. source에서 configure 메서드 재정의
  3. (http)configure 메서드에서 각종 설정을 해준다
  4. (auth)configure 메서드에서 인증 관련 설정을 해준다
    1. password를 encoding 하는 작업을 이런곳에서 함


 

스프링부트 시작 !

부트는 인텔리제이에서 수업을 듣는다.

인텔리제이 다운 , 설정

인텔리제이도 bin 폴더의 경로 환경변수에 추가

spring.start.io에서 프로젝트 다운받음

의존성은 spring web 과 lombok 추가 함

워크스페이스에 다운받은 프로젝트 폴더 넣어줌

jar , war 선택은 설명이 이럼.

jar → 톰캣 내장형

war → 톰캣이 외장형 , 밖에 있음 , 지금하고있는 web-inf/webapp 같은 구조의 프로젝트 파일

※스프링부트 파일 만들때 지정한 자바버전이랑 똑같은 버전을 설치해주어야 한다 !

다운받은 폴더 안에서 cmd 띄우고 idea . 하면 인텔리제이가 켜짐

그리고 인텔리제이가 단일프로젝트만 된다고 듣기는 했는데 한 워크스페이스 안에서 여러 프로젝트가 공존하지 않는것 뿐이지 큰 폴더 안에서 작은 폴더로 나눠서 프로젝트를 넣어주면 그냥 하나로 묶어서 정리해서 사용이 가능하다.

어플리케이션 프로퍼티 파일

spring.application.name=demo

#Tomcat Server Port Setting
server.port=8090

#UTF-8 Setting
spring.servlet.filter.encoding.filter-name=encodingFilter
spring.servlet.filter.encoding.filter-class=org.springframework.web.filter.CharacterEncodingFilter
spring.servlet.filter.encoding.init-param.encoding=UTF-8
spring.servlet.filter.encoding.init-param.forceEncoding=true
spring.servlet.filter.encoding.url-pattern=/*

# JSP Setting
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
# JSP Auto-Configuration
server.servlet.jsp.init-parameters.development=true

서버 포트 바꿔줘야함 !

build.gradle 파일

	//JSP
	implementation 'org.apache.tomcat.embed:tomcat-embed-jasper' // 추가

	//JSTL
	implementation 'jakarta.servlet:jakarta.servlet-api' //스프링부트 3.0 이상
	implementation 'jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api' //스프링부트 3.0 이상
	implementation 'org.glassfish.web:jakarta.servlet.jsp.jstl' //스프링부트 3.0 이상

추가해줘야함


인텔리제이 자바 버전 설정

gradle→ build and run using , Run tests using

둘다 인텔리제이로 설정

위에 File - setting 밑에 project structure 에 sdk 버전 자바 사용할 버전으로 바꿔주면 됨


실행시킬 때는 demoApplication 실행하면 실행됨. 이게 main 메서드인가 ?

웹상에서 창을 띄우려면 http://localhost:8090/ 식의 http도 안써도됨 localhost:포트번호/ 이렇게만 치면 되는듯함.

자동 import 컨트롤 + 알트 + O

인텔리제이는 좋은게 각종 플러그인들이 있어서 작업이 훨씬 편하게 할 수 있을것 같다. 하지만 실력향상에는 반비례로 도움이 안될수도 .. ?

 

 

'Developer Note > 국비과정 수업내용 정리&저장' 카테고리의 다른 글

24년 11월 22일  (0) 2024.11.25
24년 11월 21일  (3) 2024.11.25
24년 11월 19일  (1) 2024.11.25
24년 11월 18일  (0) 2024.11.24
24년 11월 15일  (0) 2024.11.24