YeaLow
article thumbnail

๐Ÿค์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ๊ตฌํ˜„ํ•˜๊ธฐ

  • ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋Š” ์Šคํ”„๋ง ๊ธฐ๋ฐ˜์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(์ธ์ฆ, ๊ถŒํ•œ, ์ธ๊ฐ€ ๋“ฑ)์„ ๋‹ด๋‹นํ•˜๋Š” ์Šคํ”„๋ง ํ•˜์œ„ ํ”„๋ ˆ์ž„์›Œํฌ์ž„.

1. ์ธ์ฆ์ด ์•ˆ ๋œ ์‚ฌ์šฉ์ž๋“ค์ด ์ถœ์ž…ํ•  ์ˆ˜ ์žˆ๋Š” /auth/ ๊ฒฝ๋กœ๋ฅผ UserController์— ์ถ”๊ฐ€ํ•ด ์ค€๋‹ค.

 

2. ์š”์ฒญ์ด ๋“ค์–ด์™”์„ ๋•Œ ์ธ์ฆ์ด ํ•„์š”ํ•œ์ง€, ํ•„์š”ํ•˜์ง€ ์•Š์€์ง€ ๊ตฌ๋ถ„ํ•˜๋Š” ์‹œํ๋ฆฌํ‹ฐ ํ•„ํ„ฐ๋ฅผ ๋“ฑ๋กํ•˜๋Š” SecurityConfig ํด๋ž˜์Šค ์ƒ์„ฑ

3. ์„ค์ • ํ›„ localhost:8080 ์ฃผ์†Œ๋กœ ์ ‘๊ทผํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ํ™”๋ฉด์ด ๋œจ์ง€๋งŒ

 

4. ์ธ์ฆ์—†์ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•ด๋†“์€ /auth/ ์ฃผ์†Œ๋กœ ์ ‘์†ํ•˜๋ฉด ํŽ˜์ด์ง€๊ฐ€ ์ž˜ ๋œจ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

5. ๊ธฐ์กด์— ์ž‘์„ฑํ•œ loginForm.jsp์—์„œ formํƒœ๊ทธ๋ฅผ ์ˆ˜์ •ํ•œ๋‹ค.

<form action="/auth/loginProc" method="post">

 

6.SecurityConfig ์ฝ”๋“œ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•˜๋ฉด ์œ„์˜ formํƒœ๊ทธ์— ๊ฑธ์–ด๋†“์€ /auth/loginProc ์ฃผ์†Œ๋ฅผ UserApiController์— ๋”ฐ๋กœ ๋งคํ•‘ํ•ด์ค„ ํ•„์š”๊ฐ€ ์—†๋‹ค.

 

๐Ÿค๋น„๋ฐ€๋ฒˆํ˜ธ ํ•ด์‰ฌ(์•”ํ˜ธํ™”) ๊ตฌํ˜„ํ•˜๊ธฐ

1. ์‹œํ๋ฆฌํ‹ฐ๊ฐ€ ๊ฐ–๊ณ  ์žˆ๋Š” ํ•จ์ˆ˜ ์‚ฌ์šฉ

2. JUnit ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ

์•„๋ž˜์™€ ๊ฐ™์ด ์•”ํ˜ธํ™”๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

3. UserService์— ์•”ํ˜ธํ™” ์ฝ”๋“œ ์ž‘์„ฑ

 

4. DB๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ๋‹ค์‹œ ํšŒ์›๊ฐ€์ž…์„ ํ•ด๋ณด๋ฉด ํ•ด์‰ฌํ™”๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ž˜ ๋“ค์–ด๊ฐ„ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ’กXSS & CSRF ์ฐจ์ด์ 

  • ์›น์‚ฌ์ดํŠธ ์ทจ์•ฝ์  ๊ณต๊ฒฉ์˜ ํ•˜๋‚˜๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์ž์‹ ์˜ ์˜์ง€์™€๋Š” ๋ฌด๊ด€ํ•˜๊ฒŒ ๊ณต๊ฒฉ์ž๊ฐ€ ์˜๋„ํ•œ ํ–‰์œ„(์ˆ˜์ •, ์‚ญ์ œ ๋“ฑ)๋ฅผ ํŠน์ • ์›น์‚ฌ์ดํŠธ์— ์š”์ฒญํ•˜๊ฒŒ ํ•˜๋Š” ๊ณต๊ฒฉ.
  • XSS๋ฅผ ์ด์šฉํ•œ ๊ณต๊ฒฉ์€ ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ์›น์‚ฌ์ดํŠธ๋ฅผ ์‹ ์šฉํ•˜๋Š” ์ ์„ ๋…ธ๋ฆฐ ๊ฒƒ.
  • CSRF๋Š” ํŠน์ • ์›น์‚ฌ์ดํŠธ๊ฐ€ ์‚ฌ์šฉ์ž์˜ ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์‹ ์šฉํ•˜๋Š” ์ƒํƒœ๋ฅผ ๋…ธ๋ฆฐ ๊ฒƒ.
  • ๋Œ€์‘ ๋ฐฉ์•ˆ : CSRF ํ† ํฐ ์‚ฌ์šฉ, ์‚ฌ์šฉ์ž์™€ ์ƒํ˜ธ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ ์ ์šฉ, ์žฌ์ธ์ฆ ์š”๊ตฌ
  • XSS๋Š” ๊ณต๊ฒฉ ๋Œ€์ƒ์ด ํด๋ผ์ด์–ธํŠธ, CSRF๋Š” ์„œ๋ฒ„์ด๋‹ค.
๋”๋ณด๊ธฐ
XSS๋ฅผ ์ด์šฉํ•œ ๊ณต๊ฒฉ

 

CSRF๋Š” ํŠน์ • ์›น์‚ฌ์ดํŠธ๊ฐ€ ์‚ฌ์šฉ์ž์˜ ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์‹ ์šฉํ•˜๋Š” ์ƒํƒœ๋ฅผ ๋…ธ๋ฆฐ ๊ฒƒ.

๐Ÿค์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ๋กœ๊ทธ์ธ ๊ตฌํ˜„ํ•˜๊ธฐ

1. PrincipalDetail ์ž‘์„ฑ

  • ๋กœ๊ทธ์ธํผ์—์„œ ์™„๋ฃŒ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด form submit์œผ๋กœ username, password๋ฅผ ๋„˜๊ฒจ์ค€๋‹ค.
  • SecurityConfig ํด๋ž˜์Šค์—์„œ ๋กœ๊ทธ์ธ ๊ฐ€๋กœ์ฑ„๊ณ  ์ง„ํ–‰ํ•จ.
  • ์Šคํ”„๋ง์‹œํ๋ฆฌํ‹ฐ๊ฐ€ ๋กœ๊ทธ์ธ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„์„œ ๋กœ๊ทธ์ธ ์ง„ํ–‰ํ•˜๊ณ  ์™„๋ฃŒ๊ฐ€ ๋˜๋ฉด UserDetails ํƒ€์ž…์˜ ์˜ค๋ธŒ์ ํŠธ(PrincipalDetail)๋ฅผ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์˜ ๊ณ ์œ ํ•œ ์„ธ์…˜ ์ €์žฅ์†Œ์— ์ €์žฅํ•ด์ค€๋‹ค.
@Getter
public class PrincipalDetail implements UserDetails{
	
	private User user;	//์ฝคํฌ์ง€์…˜
	
	public PrincipalDetail(User user) {
		this.user=user;
	}

	@Override
	public String getPassword() {
		
		return user.getPassword();
	}

	@Override
	public String getUsername() {
		
		return user.getUsername();
	}

	//๊ณ„์ •์ด ๋งŒ๋ฃŒ๋˜์ง€ ์•Š์•˜๋Š”์ง€ ๋ฆฌํ„ดํ•œ๋‹ค.(true : ๋งŒ๋ฃŒ ์•ˆ๋จ / false : ๋งŒ๋ฃŒ๋จ)
	@Override
	public boolean isAccountNonExpired() {
		return true;
	}

	//๊ณ„์ •์ด ์ž ๊ฒจ์žˆ์ง€ ์•Š์€์ง€ ๋ฆฌํ„ดํ•œ๋‹ค.(true:์ž ๊ธฐ์ง€ ์•Š์Œ)
	@Override
	public boolean isAccountNonLocked() {
		return true;
	}

	//๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๋งŒ๋ฃŒ๋˜์ง€ ์•Š์•˜๋Š”์ง€ ๋ฆฌํ„ดํ•œ๋‹ค.(true:๋งŒ๋ฃŒ ์•ˆ๋จ)
	@Override
	public boolean isCredentialsNonExpired() {
		return true;
	}

	//๊ณ„์ •์ด ํ™œ์„ฑํ™”(์‚ฌ์šฉ ๊ฐ€๋Šฅ)์ธ์ง€ ๋ฆฌํ„ดํ•œ๋‹ค.(true : ํ™œ์„ฑํ™”)
	@Override
	public boolean isEnabled() {
		return true;
	}

	//๊ณ„์ •์ด ์–ด๋–ค ๊ถŒํ•œ์„ ๊ฐ€์กŒ๋Š”์ง€ ๋ฆฌํ„ดํ•œ๋‹ค.
	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		
		Collection<GrantedAuthority> collectors = new ArrayList();
		//collectors.add(new GrantedAuthority() {
			
			//@Override
			//public String getAuthority() {
				//์Šคํ”„๋ง์—์„œ ROLE์„ ๋ฐ›์„ ๋•Œ ๊ทœ์น™์ž„. ROLE_ ๊ผญ ๋„ฃ์–ด์ค˜์•ผํ•จ.
				//return "ROLE_"+user.getRole();
			//}
		//});
		
		collectors.add(()->{return "ROLE_"+user.getRole();});
		
		return collectors;
	}
}

 

2. PrincipalDetailService ์ž‘์„ฑ

  • ์Šคํ”„๋ง์ด ๋กœ๊ทธ์ธ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑŒ ๋•Œ username, password ๋ณ€์ˆ˜ 2๊ฐœ๋ฅผ ๊ฐ€๋กœ์ฑ„๋Š”๋ฐ password๋ถ€๋ถ„ ์ฒ˜๋ฆฌ๋Š” ์•Œ์•„์„œํ•จ.
  • username์ด DB์— ์žˆ๋Š”์ง€๋งŒ ํ™•์ธํ•ด์„œ returnํ•ด์ฃผ๋ฉด ๋จ.

 

3. username ์ฐพ๋Š” ๋ฉ”์„œ๋“œ  UserRepository์— ์ž‘์„ฑ

//SELECT * FROM  user WHERE username = ?
	Optional<User> findByUsername(String username);

 

๐Ÿ’ก๋‹ค์‹œ ์ •๋ฆฌ

  • ๋กœ๊ทธ์ธ ์š”์ฒญ์ด ์˜ค๋Š” ์ˆœ๊ฐ„ '/auth/loginProc' ์ฃผ์†Œ๋ฅผ SecurityConfig๊ฐ€ ๊ฐ€๋กœ์ฑ”.
  • ๊ทธ ๋‹ค์Œ PrincipalDetailService๊ฐ€ ๊ฐ–๊ณ  ์žˆ๋Š” ๋ฉ”์„œ๋“œ์—์„œ username์ด ์žˆ๋Š”์ง€ ๋น„๊ต ํ›„ new PrincipalDetail(principal)๋ฅผ ๋ฆฌํ„ดํ•จ.
  • ๋ฆฌํ„ดํ•  ๋•Œ ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ์ ์€ ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ DB๋ฅผ ๋น„๊ตํ•ด์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์•”ํ˜ธํ™”ํ•œ๋‹ค.

  • ๋น„๊ต๊ฐ€ ๋๋‚˜๋ฉด principal ๊ฐ์ฒด์— ์ €์žฅ์ด ๋จ.

4. ๋กœ๊ทธ์ธ์ด ์ž˜ ๋œ๋‹ค.

profile

YeaLow

@YeaLow

ํฌ์ŠคํŒ…์ด ์ข‹์•˜๋‹ค๋ฉด "์ข‹์•„์š”โค๏ธ" ๋˜๋Š” "๊ตฌ๋…๐Ÿ‘๐Ÿป" ํ•ด์ฃผ์„ธ์š”!