Spring - ajax / security

S.Sun·2024년 4월 22일

스프링

목록 보기
12/17

질문 내용

  1. 아래에 대하여 설명하시오.
  • 인증
  • 권한
  • 인가
  1. 아래의 로그인 방법에 대하여 설명하시오.
  • token 방식
  • 쿠세-세션 방식
  • 소셜 로그인
  1. 자바스크립트에서, 게시판 CRUD의 모듈화에 대하여 정리 하시오?
  2. 스프링 시큐리티 라이브러리 3개를 정리하시오.
  3. 스프링 시큐리티에서 정적 리소스를 셋팅하는 방법은?
  4. 스프링 시큐리티에서 테스트 유저를 생성하는 방법은?(인메모리 방식)
  5. 스프링 시큐리티에서 시큐리티 에서 권한을 설정 하는 방법은?
  6. 아래가 되도록 셋팅 하시오.
유저가 admin 이고 권한이 admin 인 사람만이
/company/list 가 나오도록 하시오.

개인 작성

  • 인증(Authentication)
    - 사용자가 누구인지 확인하는 절차
  • 권한(Authorization)
    - 인증된 사용자에 한해 시스템이 부여하는 활동 권한
  • 인가(Authorization)
    - 특정 사용자가 특정 자원 및 기능에 대해 어떤 동작을 수행할 수 있는지를 결정하는 것
  • 토큰 방식(Token-based Authentication)
    - 사용자가 로그인할 때 서버로부터 토큰을 발급받아 이를 이용하여 인증
    - 주로 JWT(JSON Web Token)을 사용
    - 토큰은 클라이언트에 저장되고, 매 요청 시 헤더에 포함되어 서버에 전달
  • 쿠키-세션 방식(Cookie-Session Authentication)
    - 사용자의 세션 정보를 서버에 저장하고, 클라이언트에는 세션 식별자를 담은 쿠키를 전달하여 인증
    - 용자가 로그인하면 서버는 세션을 생성 -> 해당 세션 ID를 클라이언트에 쿠키로 전송
    -> 클라이언트는 이 쿠키를 저장 -> 매 요청 시에 서버로 전송하여 세션을 유지
  • 소셜 로그인(Social Login)
    - 사용자가 자신의 소셜 미디어 계정을 사용하여 로그인하는 방식
    - 이를 위해, OAuth 또는 OpenID Connect와 같은 프로토콜을 사용하여 사용자의 인증 및 권한 부여 처리
  • CRUD : Create Read Update Delete
  • 게시판의 CRUD 기능 모듈화 : 게시판 게시글 추가, 읽기, 수정, 삭제 기능을 모듈로 만들어서 관리
    -> CRUD 기능을 모듈화하면, 코드 관리가 쉬워지고 유지 보수가 용이해짐

board.js

/*
 * boardService 
 * 모듈 구성하기
 *    
 * 모듈 패턴은 쉽게 말해서 Java의 클래스처럼 JavaScript를 이용해서 메서드를 가지는 객체를 구성한다. 
 * 모듈 패턴은 JavaScript의 즉시 실행함수와 '{}'를 이용해서 객체를 구성한다. 
 *  
 * 
 * */

console.log("board Module..");

let boardService = (function() {

	function boardList(callback) {
		$.ajax({
			type : "GET",
			url : "/boards/list",
			success : function(result) {
				console.log(result);
				if (callback) {
					callback(result);
				}
			},
			error : function(e) {
				console.log(e);
			}
		});
	}

	function getBoard(id) {
		$.ajax({
			type : "GET",
			url : "${pageContext.request.contextPath}/boards/" + id,
			success : function(result) {
				console.log(result);
			},
			error : function(e) {
				console.log(e);
			}
		});
	}

	function deleteBoard(id){
		$.ajax({
			type:"DELETE",
			url: "${pageContext.request.contextPath}/boards/" + id,
			success: function(result){
				console.log(result);
			},
			error: function(e){
				console.log(e);
			}
		});
	}
	
	return {
		list : boardList,
		get : getBoard,
		del : deleteBoard,
	};
})();

board.js 파일을 포함시킨 파일
- 모듈화된 객체를 이용해 사용하려는 기능을 가진 함수를 호출하는 방식.

<script type="text/javascript" src="/js/board.js"></script>
<script type="text/javascript">
	$(document).ready(function(){		
		function makeList(result) {
			let htmls = "";
			
			$("#list-table").html("");
			
			$("<tr>" , {
				html : "<td>" + "번호" + "</td>" +  // 컬럼명들
						"<td>" + "이름" + "</td>" +
						"<td>" + "제목" + "</td>" +
						"<td>" + "날짜" + "</td>" +				
						"<td>" + "히트" + "</td>"
			}).appendTo("#list-table") // 이것을 테이블에 붙임

			if(result.length < 1){
				htmls.push("등록된 게시글 없습니다.");
			}else{
				$(result).each(function(){
					htmls += '<tr>';
					htmls += '<td>' + this.bid + '</td>';
					htmls += '<td>' + this.bname + '</td>';
					htmls += '<td>'					
					for(var i=0; i < this.bindent; i++) { 
	         			htmls += '-'	
	        		}
					htmls += '<a href="${pageContext.request.contextPath}/content_view?bid=' + this.bid + '">' + this.btitle + '</a></td>';
		            htmls += '<td>'+ this.bdate + '</td>'; 
	                htmls += '<td>'+ this.bhit + '</td>';
	                htmls += '<td>'+ '<input id=' + this.bid + " type='button' class='btn_delete' value='삭제'>" + '</td>';
	                htmls += '</tr>';
				}); //each end

			}

			htmls+='<tr>';
            htmls+='<td colspan="5"> <a href="${pageContext.request.contextPath}/write_view">글작성</a> </td>';		                	
            htmls+='</tr>';

			$("#list-table").append(htmls);
			
		}
        
        // 모듈에서 불러온 함수
		boardService.list(makeList);
	}
</script>
		<!-- 스프링 시큐리티 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!-- 스프링 부트에서는 jsp 태그를 지원 하지 않기 때문에 직접 입력 해야 함 -->
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-taglibs</artifactId>
		</dependency>
  • spring-boot-starter-security
    - Spring boot에서 security를 사용하기 위해 필수로 넣어줘야 함
  • spring-security-test
    - Spring security 테스트 환경 제공
  • spring-security-taglibs
    - Spring Security 태그 라이브러리


- security 설정을 하기 위해서는 다음 클래스가 필요하다.

- 5~8번은 해당 클래스 내에서 서술되는 코드라고 보면 된다.

import org.springframework.context.annotation.Configuration;
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity // 스프링 시큐리티 필터가 스프링 필터체인에 등록됨.
public class SecurityConfig extends WebSecurityConfigurerAdapter{

}

  • 우선 정적파일들은 시큐리티에 적용되지 않도록 아래와 같이 설정을 한다.
    -> 이제 더이상 리소스파일들은 스프링 시큐리티에서 관리를 하지 않는다.
   @Override
   public void configure(WebSecurity web) throws Exception {
      // web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations());
      web.ignoring().antMatchers("/css/**", "/js/**", "/imgs/**", "/lib/**");
   }
  • 정적파일을 보관하는 static 폴더 내에서, 해당 경로로 된 파일은 직접 접근할 수 있음.
    - 해당 예시에서는, 다음과 같이 /images/** 로 설정되어 있고 해당 경로 내 파일로 접근하면 다음과 같이 나온다.
	web.ignoring().antMatchers("/css/**", "/js/**", "/images/**", "/lib/**");

  • 인메모리 방식으로 테스트 유저 생성하기
   @Override
   protected void configure(AuthenticationManagerBuilder auth) throws Exception {
       auth.inMemoryAuthentication()
               .withUser("member").password("{noop}member").roles("USER").and()
               .withUser("admin").password("{noop}admin").roles("ADMIN");
   }
  • 시큐리티에서 권한 설정하기
   @Override
   protected void configure(HttpSecurity http) throws Exception {
      //우선 CSRF설정을 해제한다.
      //초기 개발시만 해주는게 좋다.
      http.csrf().disable();
       	
      http.authorizeRequests()
      .antMatchers("/member/**").hasAnyRole("ROLE_MEMBER") 
      .antMatchers("/admin/**").hasAnyRole("ROLE_ADMIN")
      .antMatchers("/**").permitAll();           
   }
  • 유저가 admin 이고, 권한이 admin 인 사람만이 /company/list 가 나오도록 하기.
  • 위 코드에서 해당되는 부분만 가져와 수정하고, 이론적인 부분 확인해보기.
	// 유저 admin 생성 및 권한 부여
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
        .withUser("member").password("{noop}member").roles("USER").and()
        .withUser("admin").password("{noop}admin").roles("ADMIN");
    }

	// 권한 설정하기
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// 우선 CSRF설정을 해제한다.
		// 초기 개발시만 해주는게 좋다.
		http.csrf().disable();
		
		// 권한 설정
		http.authorizeRequests()
		.antMatchers("/board/**").hasAnyRole("USER")
		.antMatchers("/admin/**").hasAnyRole("ADMIN")
		.antMatchers("/company/list").hasAnyRole("ADMIN")
		.antMatchers("/**").permitAll();
		
        // .antMatchers("/company/list").hasAnyRole("ADMIN") : 권한 설정할 때 사용하는 문구
        
		http.formLogin(); // 스프링 시큐리티에 있는 기본 로그인 폼을 사용하겠다.
	}
profile
두리둥둥

0개의 댓글