Spring

Shop ํ”„๋กœ์ ํŠธ Security ์ ์šฉ

byeol_dev 2023. 4. 25. 12:16

gradle์— security ์‚ฌ์šฉ์„ ์œ„ํ•ด ์•„๋ž˜ ์ฝ”๋“œ ์ถ”๊ฐ€

implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
testImplementation 'org.springframework.security:spring-security-test'

 

Security์—์„œ ์ž๋™ ๋กœ๊ทธ์ธ ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด memberController์— ์ž‘์„ฑํ•œ ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ ์ฝ”๋“œ ์‚ญ์ œ

Security๋กœ ๋กœ๊ทธ์ธ์— ๋งž์ถฐ์„œ ์ฟผ๋ฆฌ ์ˆ˜์ •.

<select id="login" resultMap="member">
    SELECT MEM_ID
        , MEM_PW
        , MEM_ROLE
    FROM SHOP_MEMBER
    WHERE MEM_ID = #{memId}
    AND MEM_STATUS != 3 <!-- ํƒˆํ‡ด ๊ณ„์ •์ด๋ฉด ์•ˆ ๋จ!  -->

</select>

SecurityConfig ํด๋ž˜์Šค ์ƒ์„ฑ

css, img, js์™€ security ์ถฉ๋Œ ๋ง‰์•„์ฃผ๋Š” ์ฝ”๋“œ ์ž‘์„ฑ.

//css,js,img security์™€ ์ถฉ๋Œ ๋ฐฉ์ง€ํ•˜๋Š” ์ฝ”๋“œ
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
    return (web) -> web.ignoring().requestMatchers("/js/**", "/css/**", "/upload/**");
}

 

์ธ์ฆ ์ธ๊ฐ€ ์„ค์ • ์ฝ”๋“œ ์ž‘์„ฑ

@Configuration
@EnableWebSecurity
public class SecurityConfig {
	
	@Bean
	public SecurityFilterChain filterChain(HttpSecurity security) throws Exception{
		
		security.csrf().disable()
				.authorizeHttpRequests()
					.requestMatchers("/"
									, "/item/itemList"
									, "/item/itemDetail"
									, "/member/isDuplicateMemId" //id ์ค‘๋ณต ์ฒดํฌ ํŽ˜์ด์ง€
									, "/member/join"
									, "/member/loginForm").permitAll()
					.requestMatchers("/admin/**").hasRole("ADMIN") //ํ•ด๋‹น ๊ถŒํ•œ๋งŒ ๋“ค์–ด์˜ฌ ์ˆ˜ ์žˆ๊ฒŒ ์ธ๊ฐ€ ์„ค์ •.
									// /admin/* ์ฝ”๋“œ ์ž‘์„ฑ ์‹œ 
									// /admin/manage (O)
									// /admin/item/manage(x)
					//.requestMatchers("/admin/**").hasAnyRole("ADMIN", "MANAGER")) //๋‘˜ ์ค‘ ํ•˜๋‚˜๋งŒ ๊ถŒํ•œ ์žˆ์œผ๋ฉด ๋“ค์–ด์˜ฌ ์ˆ˜ ์žˆ์Œ
					.anyRequest().authenticated()
				.and()
					.formLogin()
					.loginPage("/member/loginForm")
					.usernameParameter("memId")
					.passwordParameter("memPw")
					.loginProcessingUrl("/member/login") //๋กœ๊ทธ์ธ ajax์™€ ๋™์‹œ ์‹คํ–‰๋จ. ๋™์ผํ•˜๊ฒŒ ajax์—์„œ ์ด๋™ ๊ฒฝ๋กœ ๋งž์ถฐ์ฃผ๋ฉด ๋จ.
					.successHandler(getSucessHandler()) //๋กœ๊ทธ์ธ ์„ฑ๊ณต ์‹œ ์‹คํ–‰๋˜๋Š” ํด๋ž˜์Šค
					.failureHandler(getFailureHandler())
					.permitAll();
		
		return security.build();
	}
    
    //css,js,img security์™€ ์ถฉ๋Œ ๋ฐฉ์ง€ํ•˜๋Š” ์ฝ”๋“œ
	@Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().requestMatchers("/js/**", "/css/**", "/upload/**");
    }
	
	//๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™” ๊ฐ์ฒด ์ƒ์„ฑ
	@Bean
	public PasswordEncoder getPasswordEncoder() {
		return new BCryptPasswordEncoder();
	}
	
	//๋กœ๊ทธ์ธ ์‹คํŒจ ์‹œ ์‹คํ–‰๋˜๋Š” ํด๋ž˜์Šค ๊ฐ์ฒด ์ƒ์„ฑ
	@Bean
	public FailureHandler getFailureHandler() {
		return new FailureHandler();
	}
	
	//๋กœ๊ทธ์ธ ์„ฑ๊ณต ์‹œ ์‹คํ–‰๋˜๋Š” ํด๋ž˜์Šค ๊ฐ์ฒด ์ƒ์„ฑ
	@Bean
	public SucessHandler getSucessHandler() {
		return new SucessHandler();
	}
    
  }

shop ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๋กœ๊ทธ์ธ์„ ajax๋ฅผ ํ†ตํ•ด์„œ ํ•˜๊ณ  ์žˆ์Œ

> ๋กœ๊ทธ์ธ ์„ฑ๊ณต ๋ฐ ์‹คํŒจ ์‹œ ์‹คํ–‰๋˜๋Š” ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑ ํ•ด์„œ security ๋กœ๊ทธ์ธ ์„ค์ •

 

- ๋กœ๊ทธ์ธ ์„ฑ๊ณต 

SucessHandler ์ƒ์„ฑ

SimpleUrlAuthenticationSuccessHandler ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋กœ๊ทธ์ธ ์„ฑ๊ณต ์‹œ ์‹คํ–‰๋˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Œ.

์ด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์† ๋ฐ›์•„์„œ ๋ฉ”์†Œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ.

๋กœ๊ทธ์ธ ์„ฑ๊ณต ์‹œ ์‹คํ–‰๋˜๋Š” SucessHandler ํด๋ž˜์Šค๋Š” ๋กœ๊ทธ์ธ ajax์™€ ๋™์‹œ์— ์‹คํ–‰๋จ.

ajax๋ฅผ ํ†ตํ•ด ๋กœ๊ทธ์ธํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋กœ๊ทธ์ธ ์„ฑ๊ณต ํ›„ ajax์˜ success ๊ตฌ๋ฌธ์œผ๋กœ ๋Œ์•„๊ฐ€์„œ ํŽ˜์ด์ง€ ์ด๋™.

public class SucessHandler extends SimpleUrlAuthenticationSuccessHandler{
	
	//๋กœ๊ทธ์ธ ์„ฑ๊ณต ์‹œ ์‹คํ–‰๋˜๋Š” ํด๋ž˜์Šค
	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException {

		System.out.println("success handler ์‹คํ–‰~");
		
		//์ž๋ฐ”์—์„œ html ๊ธ€์ž ๊ทธ๋ฆฌ๋Š” ์ฝ”๋“œ
		PrintWriter p = response.getWriter();
		p.write("success"); //๋กœ๊ทธ์ธ ์„ฑ๊ณตํ•˜๋ฉด ์ด ํด๋ž˜์Šค์™€ header.js์˜ ajax(๋กœ๊ทธ์ธํ•˜๋Š”) ๋™์‹œ์— ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋กœ๊ทธ์ธ ํ›„ success ๊ตฌ๋ฌธ์œผ๋กœ ๋Œ์•„๊ฐ.
							//success๋ผ๋Š” ๊ธ€์ž๋ฅผ ajax์˜ success ๊ตฌ๋ฌธ result๋กœ ๋ฐ›์•„๊ฐ€๋Š” ๊ฒƒ.
		p.flush();
		
		//super.onAuthenticationSuccess(request, response, authentication);
	}
	
	
}

 

 

-๋กœ๊ทธ์ธ ์‹คํŒจ

FailureHandler ์ƒ์„ฑ

SimpleUrlAuthenticationFailureHandler ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋กœ๊ทธ์ธ ์‹คํŒจ ์‹œ ์‹คํ–‰๋˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Œ.

์ด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์† ๋ฐ›์•„์„œ ๋ฉ”์†Œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ.

๋กœ๊ทธ์ธ ์‹คํŒจ ์‹œ ์‹คํ–‰๋˜๋Š” FailureHandler ํด๋ž˜์Šค๋Š” ๋กœ๊ทธ์ธ ajax์™€ ๋™์‹œ์— ์‹คํ–‰๋จ.

๋กœ๊ทธ์ธ ์‹คํŒจ ์‹œ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๊ฐ€ ๋œจ๊ฒŒ ์˜ˆ์™ธ์ฒ˜๋ฆฌ ์„ค์ •.

๋‹ค์‹œ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๊ฐ€๋„ ์ด์ „์— ์ž…๋ ฅํ•œ id๊ฐ’ ๋‚จ์•„ ์žˆ๊ฒŒ memId ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ๊ฐ€์•ผํ•จ.

ajax๋ฅผ ํ†ตํ•ด ๋กœ๊ทธ์ธํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋กœ๊ทธ์ธ ์‹คํŒจ ํ›„ header.js์˜ ๋กœ๊ทธ์ธ ajax success ๊ตฌ๋ฌธ์œผ๋กœ ๋Œ์•„๊ฐ€์„œ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ํ™”๋ฉด์— ๋ฟŒ๋ ค์ค€๋‹ค.

//๋กœ๊ทธ์ธ ์‹คํŒจ ์‹œ ์ž๋™์œผ๋กœ ์‹คํ–‰๋˜๋Š” ํด๋ž˜์Šค
public class FailureHandler extends SimpleUrlAuthenticationFailureHandler{

	@Override
	public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
			AuthenticationException exception) throws IOException, ServletException {
		
		//์—๋Ÿฌ ๋ฉ”์„ธ์ง€
		String eMsg = "";
		
		if(exception instanceof BadCredentialsException) {
			eMsg = "์•„์ด๋”” ํ˜น์€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.";
		}
		else if(exception instanceof UsernameNotFoundException) {
			eMsg = "๊ณ„์ •์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.";
		}
		else {
			eMsg = "์•Œ ์ˆ˜ ์—†๋Š” ์ด์œ ๋กœ ๋กœ๊ทธ์ธ์— ์‹คํŒจํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ด€๋ฆฌ์ž์—๊ฒŒ ๋ฌธ์˜ํ•˜์‹ญ์‹œ์˜ค.";
		}
		
		//๋กœ๊ทธ์ธ ์‹œ ์ž…๋ ฅํ•œ id๊ฐ’
		String memId = request.getParameter("memId");

		//java์—์„œ html๋กœ ํ…์ŠคํŠธ ๋ณด๋ƒ„(?
		PrintWriter p = response.getWriter();
		p.write("fail");
		p.flush();
				
	}

}

 

header.js ์ˆ˜์ •

//๋กœ๊ทธ์ธ ํ•จ์ˆ˜
function login(){
						//joinModal์—๋„ memId ์žˆ์Œ ์˜์—ญ ์ •ํ™•ํ•˜๊ฒŒ ์ง€์ •. ๋ณดํ†ต ๊ฒน์น˜๊ฒŒ ์ž‘์„ฑx
	const memId = document.querySelector('#loginModal #memId').value;
	const memPw = document.querySelector('#loginModal #memPw').value;
	
	//ajax start
	$.ajax({
		url: '/member/login', //์š”์ฒญ๊ฒฝ๋กœ (security, ajax ์ฝ”๋“œ ๋™์‹œ ์‹คํ–‰๋จ.)
		type: 'post',
		data: { 'memId' : memId, 'memPw' : memPw }, //ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ
		//success๋Š” ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•œ ๊ฒƒ.
		success: function(result) {  //์‹œํ๋ฆฌํ‹ฐ ๋กœ๊ทธ์ธ ์„ฑ๊ณต ํ›„ ์‹คํ–‰๋˜๋Š” ํด๋ž˜์Šค์—์„œ ๋ณด๋‚ธ success ๊ธ€์ž result์— ๋ฐ›์•„์˜ด.
			//๋กœ๊ทธ์ธ ์„ฑ๊ณต ์‹œ true 
			if(result == 'success') { 
				location.href = '/'; //์ธ๋ฑ์Šค ์ปจํŠธ๋กค๋Ÿฌ ํŽ˜์ด์ง€๋กœ ์ด๋™ > ์ƒํ’ˆ ๋ชฉ๋ก ํ™”๋ฉด ์ด๋™
			}
			//๋กœ๊ทธ์ธ ์‹คํŒจ (์•„์ด๋”” ๋ฐ‘ ๋นจ๊ฐ„ ๊ธ€์ž)
			else{
				//alert('๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.');
				
				//๋กœ๊ทธ์ธ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€
				//๋กœ๊ทธ์ธ ์‹คํŒจ ์‹œ ์ถ”๊ฐ€๋˜๋Š” div ํƒœ๊ทธ ์‚ญ์ œ(๋ฌธ๊ตฌ ์‹คํŒจํ•œ ์ˆ˜๋งŒํผ ๋œจ๋Š” ๊ฒƒ ๋ฐฉ์ง€)
				const error_div = document.querySelector('#errorDiv');

				if (error_div != null) {
					error_div.remove();
				}	
				
			//๋กœ๊ทธ์ธ ์‹คํŒจ ์‹œ ์˜ค๋ฅ˜ ๋ฌธ๊ตฌ
			let str = '';
	        str += '<div id="errorDiv" style="color: red; font-size: 0.9rem;">';
	        str += '๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.';
	        str += '</div>';
	     
	        const login_error_div = document.querySelector('#loginErrorDiv');
	        login_error_div.insertAdjacentHTML('beforeend', str);
				
				
				//id, pw input ํƒœ๊ทธ ์ดˆ๊ธฐํ™” (๋กœ๊ทธ์ธ ๋ฒ„ํŠผ ๋นผ๊ณ  ๋‹ค ๋“ค๊ณ ์™€์•ผ ๋ผ์„œ All)
				//์ƒˆ๋กœ์šด for๋ฌธ							//ํƒ€์ž…์ด ๋ฒ„ํŠผ์ธ ๊ฒƒ ์ œ์™ธํ•˜๊ณ  input ํƒœ๊ทธ ๋‹ค ์„ ํƒ.
				document.querySelectorAll('#loginModal input:not([type="button"])').forEach(function(t, index){
					t.value;  //input ํƒœ๊ทธ ์ž์ฒด๊ฐ€ t์ž„.
				});
				
				/*์ž์ฃผ ์“ฐ๋˜ for๋ฌธ
				 const tags = document.querySelectorAll('#loginModal input:not([type="button"])');
				
				 for(const t of tags) {
					t.value = '';
				} */
				
				
			}
		},
		error: function() {
			alert('์‹คํŒจ');
		}
	});
//ajax end
}

๋กœ๊ทธ์ธ ์‹คํŒจ ์‹œ ์•„๋ž˜์ฒ˜๋Ÿผ ์•„์ด๋””๊ฐ’ ๋‚จ์•„ ์žˆ๊ณ , ๋กœ๊ทธ์ธ ์ •๋ณด ํ™•์ธํ•˜๋ผ๋Š” ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ๋œธ

 

header ๋ถ€๋ถ„ ๋ฒ„ํŠผ ์ธ์ฆ ์ธ๊ฐ€ ์ปจํŠธ๋กค

header.html์— ์‹œํ๋ฆฌํ‹ฐ ๋ฌธ๋ฒ• ์‚ฌ์šฉ์„ ์œ„ํ•ด ์•„๋ž˜ ์ฝ”๋“œ ์ถ”๊ฐ€

xmlns:sec="http://www.thymeleaf.org/extras/spring-security"

000๋‹˜ ๋ฐ˜๊ฐ‘์Šต๋‹ˆ๋‹ค. ๋ฌธ๊ตฌ ๋ฐ MYPAGE, LOGOUT ๋ฒ„ํŠผ ์ธ์ฆ ๋์„ ๋•Œ๋งŒ ๋ณด์ด๊ฒŒ ๋ณ€๊ฒฝ.

<span sec:authorize="isAuthenticated()">
    [[${#authentication.name}]]๋‹˜ ๋ฐ˜๊ฐ‘์Šต๋‹ˆ๋‹ค. <!-- ๋กœ๊ทธ์ธํ•œ ์‚ฌ๋žŒ id -->
    <a th:href="@{/cart/cartList}">MY PAGE</a>
    <a th:href="@{/member/logout}">LOGOUT</a>
</span>

 

LOGIN, JOIN ๋ฒ„ํŠผ ์ธ์ฆ ์•ˆ ๋์„ ๋•Œ ๋ณด์ด๊ฒŒ

<span sec:authorize="isAnonymous()">
    <span data-bs-toggle="modal" data-bs-target="#loginModal" style="cursor: pointer;">LOGIN</span>
    <span data-bs-toggle="modal" data-bs-target="#joinModal" style="cursor: pointer;">JOIN</span>
</span>

 

Security ๋กœ๊ทธ์•„์›ƒ ๊ธฐ๋Šฅ

์šฐ์„  MemberController ๋กœ๊ทธ์•„์›ƒ ์ฝ”๋“œ ์‚ญ์ œ

SecurityConfig์— ๋กœ๊ทธ์•„์›ƒ ์‹œ ์„ค์ • ์ฝ”๋“œ ์ถ”๊ฐ€

@Bean
public SecurityFilterChain filterChain(HttpSecurity security) throws Exception{

    security.csrf().disable()
            .authorizeHttpRequests()
                .requestMatchers("/"
                                , "/item/itemList"
                                , "/item/itemDetail"
                                , "/member/isDuplicateMemId"
                                , "/member/join"
                                , "/member/loginForm").permitAll()
                .anyRequest().authenticated()
            .and()
                .formLogin()
                .loginPage("/member/loginForm")
                .usernameParameter("memId")
                .passwordParameter("memPw")
                .loginProcessingUrl("/member/login")
                .successHandler(getSucessHandler())
                .failureHandler(getFailureHandler())
                .permitAll()
            .and()
                .logout()
                .logoutUrl("/member/logout")
                .invalidateHttpSession(true)
                .logoutSuccessUrl("/"); //

    return security.build();
}

 

๊ฐ๊ฐcontroller ์ˆ˜์ •

session ์ •๋ณด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋“ค ์ˆ˜์ •ํ•ด์•ผ ํ•จ.

admincontroller ์นดํ…Œ๊ณ ๋ฆฌ ๊ด€๋ฆฌ ํŽ˜์ด์ง€ ์„ธ์…˜ ๋ฉ”์†Œ๋“œ ์ง€์šฐ๊ธฐ

id ๋ฝ‘๋Š” ์‹œํ๋ฆฌํ‹ฐ ์ฝ”๋“œ ์‚ฌ์šฉ.

//์นดํ…Œ๊ณ ๋ฆฌ ๊ด€๋ฆฌ ํŽ˜์ด์ง€
@GetMapping("/cateManage")
public String cateManage(Model model, AdminSubMenuVO adminSubMenuVO) {

    //๊ด€๋ฆฌ์ž๋กœ ๋กœ๊ทธ์ธ ํ•œ ๊ฒฝ์šฐ ์ฒซ ํŽ˜์ด์ง€ ์นดํ…Œ๊ณ ๋ฆฌ ํŽ˜์ด์ง€๋กœ ์ด๋™.(๊ฐ€์ ธ๊ฐ€๋Š” ๋ฐ์ดํ„ฐ X)
    //์ธ๋ฑ์Šค ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์˜ฌ ๋•Œ๋Š” ๋ฐ์ดํ„ฐ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ธŒ ๋ฉ”๋‰ด ์ฝ”๋“œ ๋ฐ์ดํ„ฐ ๋„ฃ๊ธฐ.
    adminSubMenuVO.setMenuInfo(ConstVariable.DEFAULT_MENU_CODE, ConstVariable.DEFAULT_SUB_MENU_CODE_1);

    //์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ์กฐํšŒ
    model.addAttribute("cateList", adminService.getCateListForAdmin());
    //model.addAttribute("menuCode", "MENU_001"); //์ธํ„ฐ์…‰ํ„ฐ์—์„œ ๋ฐ์ดํ„ฐ ๋ฐ›์„ ๋•Œ ๋„˜๊ธฐ๋Š” ๋ฐ์ดํ„ฐ ์ด๋ฆ„์ด key๊ฐ€ ๋จ
    //model.addAttribute("MemberVO", new MemberVO());

    return "content/admin/cate_manage";
}

buycontroller ๋ฐ”๋กœ ๊ตฌ๋งค ๊ธฐ๋Šฅ

memId ๊ตฌํ•˜๋Š” ์ฝ”๋“œ ์ˆ˜์ •

๋งค๊ฐœ๋ณ€์ˆ˜ authentication ์ถ”๊ฐ€ ํ›„ ์‹œํ๋ฆฌํ‹ฐ ๋ฌธ๋ฒ• ์‚ฌ์šฉ

๋ฐ”๋กœ๊ตฌ๋งค

์„ ํƒ๊ตฌ๋งค

๊ตฌ๋งค๋‚ด์—ญ ํŽ˜์ด์ง€

cartController

์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ƒํ’ˆ ๋“ฑ๋ก

์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€

 

config ์ธ์ฆ ์ธ๊ฐ€ ์ˆ˜์ •

์ผ๋ฐ˜ ํšŒ์›์ด url ์ฃผ์†Œ๋ฅผ ์•Œ๊ณ  ์žˆ์œผ๋ฉด admin ๊ด€๋ จ ํŽ˜์ด์ง€ ์ด๋™ ๊ฐ€๋Šฅ

์„ค์ •ํ•ด์ค˜์•ผ ํ•จ.

์•„๋ž˜ ์ฝ”๋“œ ์ถ”๊ฐ€

.requestMatchers("/admin/**").hasRole("ADMIN") //ํ•ด๋‹น ๊ถŒํ•œ๋งŒ ๋“ค์–ด์˜ฌ ์ˆ˜ ์žˆ๊ฒŒ ์ธ๊ฐ€ ์„ค์ •.


user๋กœ ๋กœ๊ทธ์ธ ํ•ด๋„ ์ด์ œ ๊ถŒํ•œ ์—†์–ด์„œ ์˜ค๋ฅ˜์ฒ˜๋Ÿผ ํŽ˜์ด์ง€ ๋œธ

์ธ๊ฐ€๊ฐ€ ์•ˆ ๋‚˜์„œ ํŠ•๊ฒผ์„ ๊ฒฝ์šฐ

๊ถŒํ•œ ์—†๋‹ค๊ณ  ์•Œ๋ ค์ฃผ๋Š” ํŽ˜์ด์ง€ ์„ค์ • ๊ฐ€๋Šฅ.

indexController์— ์ปจํŠธ๋กค๋Ÿฌ ์ฝ”๋“œ ์ถ”๊ฐ€

//๋ฏธ์ธ๊ฐ€ ์‹œ ์ด๋™ํ•  ํŽ˜์ด์ง€
@GetMapping("/accessDeny")
public String accessDeny() {

    return "content/access_deny";
}

content์— html ์ƒ์„ฑ 

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
	xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>์ ‘๊ทผ์ด ๊ฑฐ๋ถ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.</h3>
<h5><a th:href="@{/}">ํ™ˆ์œผ๋กœ ๊ฐ€๊ธฐ</a></h5>
</body>
</html>

 

 

์‹œํ๋ฆฌํ‹ฐ ์ ์šฉ ํ›„ ๊ธฐ๋Šฅ ์˜ค๋ฅ˜ ์žก๊ธฐ

- ๊ด€๋ฆฌ์ž ๋กœ๊ทธ์ธ ์‹œ ๊ด€๋ฆฌ์ž ์ƒ๋‹จ ๋ฉ”๋‰ด ์˜ค๋ฅ˜

header.html ์ˆ˜์ •

๋กœ๊ทธ์ธ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ๋ฉ”๋‰ด ๋‚˜์˜ค๋Š” ์ฝ”๋“œ ์ˆ˜์ • ํ•„์š” session ์•ˆ ์“ฐ๊ธฐ ๋•Œ๋ฌธ์— ์กฐ๊ฑด๋ฌธ ์ง€์›Œ์ฃผ๊ณ 

์‹œํ๋ฆฌํ‹ฐ ๋ฌธ๋ฒ• ์‚ฌ์šฉํ•˜์—ฌ ์•„๋ž˜์ฒ˜๋Ÿผ ์ฝ”๋“œ ์ˆ˜์ •

<ul class="navbar-nav">
<!-- ๋กœ๊ทธ์ธ X -->
<th:block sec:authorize="isAnonymous()">
    <th:block th:each="category : ${categoryList}">
        <li class="nav-item">
            <a class="nav-link">[[${category.cateName}]]</a> 
        </li>
    </th:block>
</th:block>

<th:block sec:authorize="isAuthenticated()">
    <!-- ๋กœ๊ทธ์ธ O, ์ผ๋ฐ˜ํšŒ์› -->
    <th:block sec:authorize="hasRole('ROLE_USER')">
        <th:block th:each="category : ${categoryList}">
            <li class="nav-item">
                <a class="nav-link">[[${category.cateName}]]</a> 
            </li>
        </th:block>
    </th:block>
    <!-- ๋กœ๊ทธ์ธ O, ๊ด€๋ฆฌ์ž -->
    <th:block sec:authorize="hasRole('ROLE_ADMIN')">
        <th:block th:each="adminMenu : ${adminMenuList}">
            <li class="nav-item">
                <a class="nav-link" th:href="@{'/admin' + ${adminMenu.menuUrl}(menuCode=${adminMenu.menuCode})}">[[${adminMenu.menuName}]]</a> 
            </li>
        </th:block>
    </th:block>
</th:block>

</ul>

 

- ์ƒํ’ˆ ์ƒ์„ธ ํŽ˜์ด์ง€ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํด๋ฆญ ์‹œ ๋กœ๊ทธ์ธ ์ธ์‹ ๋ชป ํ•˜๋Š” ์˜ค๋ฅ˜

item_detail.html 

์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์„ธ์…˜์œผ๋กœ memId ๊ฐ€์ ธ๊ฐ€๊ฒŒ ๋˜์–ด ์žˆ์Œ > ์ˆ˜์ •

<input type="button" class="btn btn-outline-success" value="์žฅ ๋ฐ” ๊ตฌ ๋‹ˆ" 						
    th:onclick="regCart([[${#authentication.name}]], [[${item.itemCode}]]);">

security๋Š” ๋กœ๊ทธ์ธ ํ•˜์ง€ ์•Š์€ ์ƒํƒœ์—๋„ ์ต๋ช…์œผ๋กœ ์ž„์‹œ ์•„์ด๋””๋ฅผ ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์— ์œ ์˜!

์—ฐ๊ฒฐ๋œ item_detail.js์˜ regCart ํ•จ์ˆ˜ ์ˆ˜์ •

์ต๋ช…์œผ๋กœ ์ž„์‹œ ์•„์ด๋””์ธ anonymousUser ๊ฒฝ์šฐ์— ๋กœ๊ทธ์ธ ํ•˜๊ฒŒ ์„ค์ •.