Skip to content

๐Ÿ™Œ 2๋‹จ๊ณ„ - ์ธ๊ฐ€(Authorization) ๋ฆฌ๋ทฐ ์š”์ฒญ ๋“œ๋ฆฝ๋‹ˆ๋‹ค. #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Feb 12, 2025

Conversation

parkjun5
Copy link

@parkjun5 parkjun5 commented Feb 9, 2025

์•ˆ๋…•ํ•˜์„ธ์š”.
์ธ๊ฐ€(Authorization) ๋ฆฌ๋ทฐ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฒˆ ๋ฏธ์…˜์—์„œ ๊ตฌํ˜„ํ•  ๋‚ด์šฉ์€ ์ ์—ˆ์ง€๋งŒ ์ดํ•ด ํ•˜๋Š” ๊ฒŒ ์‰ฝ์ง€ ์•Š์•˜๋˜ ๊ฒƒ ๊ฐ™์•„์š”.

ํŠนํžˆ RequestMatcherDelegatingAuthorizationManager๊ฐ€ ํ•œ๋ฒˆ์— ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค.
๊ถŒํ•œ ์ธ๊ฐ€ ์ฒ˜๋ฆฌ๋ฅผ ํ•  ๋•Œ์— AOP๋ฅผ ์“ด๋‹ค๋ฉด ์ธํ„ฐ์…‰ํ„ฐ๋‚˜ Aspect๋ฅผ ์‚ฌ์šฉ๋  ๊ฒƒ ์ธ๋ฐ, ํ•„ํ„ฐ์™€ ์‚ฌ์šฉ๋˜๋Š” ๊ณณ๋„ ์ฒ˜๋ฆฌ๋„ ๋‹ค๋ฅด๋‹ค๊ณ  ์ƒ๊ฐ์ด ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ AuthorizationManager ์ค‘์— ํ•„ํ„ฐ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ข…๋ฅ˜์™€ ์ธํ„ฐ์…‰ํ„ฐ์™€ Aspect์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ข…๋ฅ˜๋ฅผ ๊ตฌ๋ถ„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด AuthorityAuthorizationManager ์—์„œ ํ•„ํ„ฐ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ถŒํ•œ ์ธ๊ฐ€ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ณ , SecuredAuthorizationManager ์ธํ„ฐ์…‰ํ„ฐ( ์–ด๋…ธํ…Œ์ด์…˜) ๊ธฐ๋ฐ˜์œผ๋กœ ๋‹ค์‹œ ํ•œ๋ฒˆ ๊ถŒํ•œ ์ธ๊ฐ€ ์ฒ˜๋ฆฌ๊ฐ€ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ๊ถŒํ•œ ์ธ๊ฐ€ ์ฒ˜๋ฆฌ๊ฐ€ ์ค‘๋ณต์ด ๋˜๊ณ  ์žˆ๋Š” ๊ฒƒ ์•„๋‹Œ๊ฐ€ ํ•˜๋Š” ๊ถ๊ธˆ์ฆ๋„ ์ƒ๊ธฐ๋„ค์š”!

๋ฆฌ๋ทฐ ์ž˜ ๋ถ€ํƒ ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

 - more test for new API
 - ํ•˜๋‚˜์˜ ํ•„ํ„ฐ์—์„œ ์—ฌ๋Ÿฌ ์ธ๊ฐ€ ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๋ณ€๊ฒฝ
  - ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž ์ฒดํฌ๋ฅผ ์œ„ํ•œ AuthorityAuthorizationManager
  - ๊ถŒํ•œ ์ฒดํฌ๋ฅผ ์œ„ํ•œ SecuredAuthorizationManager ์ถ”๊ฐ€
 - MvcRequestMatcher for matching by HttpMethod And URI
 - AnyRequestMatcher for matching any request
 - ์ธ๊ฐ€๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋งค๋‹ˆ์ ธ๋“ค ์ƒ์„ฑ
 - AuthenticatedAuthorizationManager ๋‹จ์ˆœ ์ธ์ฆ ํ™•์ธ
 - AuthorityAuthorizationManager ๋ฉ”์„œ๋“œ์—์„œ ์–ด๋…ธํ…Œ์ด์…˜์„ ๊ฐ€์ ธ์™€ ๊ถŒํ•œ ํ™•์ธ
 - PermitAllAuthorizationManager ๋ชจ๋“  ์š”์ฒญ ํ—ˆ์šฉ
 - DenyAllAuthorizationManager ๋ชจ๋“  ํ—ˆ์šฉ ๊ฑฐ๋ถ€
 - ์œ ์ € ๊ถŒํ•œ ์ œ์–ด๋ฅผ Interceptor์—๊ฒŒ ์œ„์ž„ํ•˜๊ธฐ ์œ„ํ•œ Secured ์–ด๋…ธํ…Œ์ด์…˜ ์ถ”๊ฐ€
โ€ฆizationManager

 - ์ธํ„ฐ์…‰ํ„ฐ์™€ ํ•„ํ„ฐ๋Š” ๋”์ด์ƒ ์ง์ ‘ ์ธ๊ฐ€๋ฅผ ํ•ด์ฃผ์ง€ ์•Š๊ณ , AuthorizationManager ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
โ€ฆnged

 - RequestMatcherDelegatingAuthorizationManager ์—์„œ ์š”์ฒญ์— ๋งž๋Š” ์ธ๊ฐ€๋ฅผ ์‹œ๋„ํ•œ๋‹ค.
 - ํ•„ํ„ฐ๋Š” ํ•œ๊ณณ์—์„œ ์—ฌ๋Ÿฌ ์ธ๊ฐ€๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€๋งŒ, MethodInterceptor or Aspect ์—์„œ๋Š” ํ•˜๋‚˜์˜ ์ธ๊ฐ€๋ฅผ ์ฒ˜๋ฆฌ ๊ทธ๋ž˜์„œ ๊ตณ์ด ํ•ฉ์ณ์„œ ์ฒ˜๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†๋Š”๋“ฏํ•จ. ๋งŒ์•ฝ ํ•„์š”ํ•˜๋‹ค๋ฉด RequestMatcher ํ˜•์‹์œผ๋กœ Annotation ์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›๋„๋ก ์ฒ˜๋ฆฌ?
 - RequestMatcherDelegatingAuthorizationManager ๋Š” HttpServletRequest ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋งค๋‹ˆ์ €๋งŒ ๋“ฑ๋ก(Filter ์‚ฌ์šฉํ•˜๋Š” ์• ๋“ค)
 - AuthorityAuthorizationManager ํ•„ํ„ฐ์—์„œ ์ •ํ•ด์ง„ ๊ฐ’๊ณผ Authentication.getAuthorities() ๋น„๊ต
 - SecuredMethodInterceptor ์ธํ„ฐ์…‰ํ„ฐ์—์„œ Annotation ๊ฐ’๊ณผ Authentication.getAuthorities() ๋น„๊ต
Copy link

@jinyoungchoi95 jinyoungchoi95 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์•ˆ๋…•ํ•˜์„ธ์š” ์„ธ์ค€๋‹˜ ๐Ÿ˜„

Authorization ๋ฏธ์…˜์„ ํ•จ๊ป˜ํ•˜๊ฒŒ ๋œ ์ตœ์ง„์˜์ž…๋‹ˆ๋‹ค.

๋ฏธ์…˜ ์ž˜ ์ง„ํ–‰ํ•ด์ฃผ์…จ๋„ค์š” ๐Ÿ‘ ๋ช‡๊ฐ€์ง€ ์ฝ”๋ฉ˜ํŠธ ๋‚จ๊ฒจ๋‘์—ˆ์œผ๋‹ˆ ํ™•์ธ๋ถ€ํƒ๋“œ๋ ค์š” ๐Ÿ˜„

๊ถ๊ธˆํ•˜๊ฑฐ๋‚˜ ๊ณ ๋ฏผ์ด ๋˜๋Š” ๋ถ€๋ถ„์ด ์žˆ์œผ์‹œ๋‹ค๋ฉด ์–ธ์ œ๋“  pr ์ฝ”๋ฉ˜ํŠธ ๋˜๋Š” dm์œผ๋กœ ์š”์ฒญ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.
๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ๐Ÿ™‡โ€โ™‚๏ธ

import java.lang.reflect.Method;
import java.util.Arrays;

public class SecuredAuthorizationManager implements AuthorizationManager<MethodInvocation> {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์กฐ๊ธˆ ํ—ท๊ฐˆ๋ฆฌ์‹ค ์ˆ˜ ์žˆ์„ ๋ฒ•ํ•œ ๋ถ€๋ถ„์ด๋ผ๊ณ  ์ƒ๊ฐํ•ด์š”. ๋‘๊ฐ€์ง€๋ฅผ ๋ถ„๋ฆฌํ•ด๋†“๊ณ  ์ƒ๊ฐํ•ด๋ณด๋ฉด,

SecuredAuthorizationManager๋Š” @Secured ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ณด๊ณ  ์ธ๊ฐ€ ๊ณผ์ •์„ ์ฒดํฌํ•˜๋Š” ๊ฒƒ์ด๊ณ , AuthorityAuthorizationManager ๋Š” ๋ช…ํ™•ํ•˜๊ฒŒ ์ธ๊ฐ€ ์ฒ˜๋ฆฌ๋ฅผ ์ง์ ‘ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฐ์ฒด์—์š”.

๊ทธ๋ž˜์„œ ์‚ฌ์‹ค ์–ด๋–ป๊ฒŒ๋ณด๋ฉด SecuredAuthorizationManager์™€ AuthorityAuthorizationManager๋Š” ๋ถ„๋ฆฌ๋˜์–ด์žˆ๋‹ค๊ธฐ๋ณด๋‹ค๋Š” ์‹ค์ œ๋กœ๋Š” SecuredAuthorizationManager๊ฐ€ AuthorityAuthorizationManager๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , @Secured์—์„œ ๊บผ๋‚ธ ๊ฒƒ์„ ๊ฐ€์ง€๊ณ  AuthorityAuthorizationManager๋กœ ๋‹ค์‹œ ๊ฒ€์ฆ์„ ์ง„ํ–‰ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์–ด์š”. ๋ช…ํ™•ํ•˜๊ฒŒ ์šฉ๋„ ์ž์ฒด๊ฐ€ ๋ถ„๋ฆฌ๋˜์–ด์žˆ๊ณ , ๊ณตํ†ตํ™”๋œ ์ธ๊ฐ€์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋ฅผ SecuredAuthorizationManager๏ฟฝ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š”๊ฑฐ์ฃ . (์‹ค์ œ๋กœ๋Š” ๋‹จ์ผ ๊ถŒํ•œ๋งŒ ๊ฒ€์ฆํ•˜๊ธฐ ๋ณด๋‹ค๋Š” Authorities๋กœ ๋‹ค์ค‘ ๊ถŒํ•œ์„ ๊ฐ€์ง€๊ณ  ์ฒดํฌํ•ฉ๋‹ˆ๋‹ค.)

https://github.com/spring-projects/spring-security/blob/main/core/src/main/java/org/springframework/security/authorization/method/SecuredAuthorizationManager.java

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SecuredAuthorizationManager ์—์„œ ์ •ํ™•ํ•œ ์ธ๊ฐ€ ์ฒ˜๋ฆฌ๋ฅผ AuthorityAuthorizationManager ๋ฅผ ์œ„์ž„ํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๊ฒ ๋„ค์š”.
AuthorityAuthorizationManager์—์„œ๋„ ์ œ๋„ค๋ฆญ์„ ํ†ตํ•ด ์ „๋‹ฌ๋ฐ›์€ ํŒŒ๋ผ๋ฏธํ„ฐ์— ๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ๋„ ์žˆ์„ ๊ฒƒ ๊ฐ™์•„์š”.

์ œ๊ฐ€ ์ดํ•ดํ•œ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•˜๋ฉด SecuredAuthorizationManager ๋Š” ์ธ๊ฐ€์— ํ•„์š”ํ•œ ๊ฐ’์„ ์–ด๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ ์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ SecuredAuthorizationManager ๋Š” ์ •ํ™•ํžˆ ์–ด๋–ค ์ธ๊ฐ€ ์ž‘์—…์„ ํ• ์ง€๋Š” ๊ด€์‹ฌ์ด ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ AuthorityAuthorizationManager ์—๊ฒŒ ์ธ๊ฐ€ ์ž‘์—…์„ ์œ„์ž„ํ•ฉ๋‹ˆ๋‹ค.
์ œ๋„ค๋ฆญ์„ ์‚ฌ์šฉํ•˜๋Š” AuthorityAuthorizationManager ์—์„œ๋Š” ๊ตฌํ˜„์ฒด๋‚˜ ์ œ๋„ค๋ฆญ ๊ฐ’์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ „๋‹ฌ ๋ฐ›์€ ๊ฐ’๊ณผ Authentication ์„ ํ†ตํ•ด์„œ ์ธ๊ฐ€๋ฅผ ์ž‘์—…ํ•ด์ฃผ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๋„ค ์ดํ•ดํ•ด์ฃผ์‹  ๋‚ด์šฉ์ด ๋งž์Šต๋‹ˆ๋‹ค :)

README.md Outdated

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ํ•„์š” ์š”๊ตฌ์‚ฌํ•ญ ์ž˜ ์ •๋ฆฌํ•ด์ฃผ์…จ๋„ค์š” ๐Ÿ‘

}
// @Bean
// public SecuredAspect securedAspect() {
// return new SecuredAspect();
// }

@Bean
public RequestMatcherDelegatingAuthorizationManager requestMatcherDelegatingAuthorizationManager() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ ์ ˆํ•˜๊ฒŒ ์ž˜ ์ถ”๊ฐ€ํ•ด์ฃผ์…จ๋„ค์š” :)

Comment on lines 10 to 16
public static AuthorizationDecision granted() {
return new AuthorizationDecision(true);
}

public static AuthorizationDecision denied() {
return new AuthorizationDecision(false);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๋ฉ”์†Œ๋“œ๋กœ ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ๊ฒฐ๊ตญ ๋™์ผํ•œ ๊ฐ์ฒด๋ฅผ ์—ฌ๋Ÿฌ๋ฒˆ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆ๋ณ€ํ•œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ํ˜„์žฌ ์ƒํ™ฉ์ด๋ผ๋ฉด ๋‹จ์ˆœํžˆ ์ƒ์ˆ˜๋กœ ๋งŒ๋“ค๊ณ  ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๋ฐฉ๋ฒ•์ด ๋˜๊ฒ ๋„ค์š” :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AuthorizationDecision ์—์„œ ์„ฑ๊ณต ์‹คํŒจ๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ข‹์€ ๋ฐฉ๋ฒ•์ด๋„ค์š”.

return;
AuthorizationDecision authorizationDecision = authorizationManager.checkInFilter(request, authentication);
if (authorizationDecision.isDenied()) {
throw new AuthenticationException();
Copy link

@jinyoungchoi95 jinyoungchoi95 Feb 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ธ๊ฐ€๊ถŒํ•œ์ด ๊ฑฐ์ ˆ๋˜์—ˆ๋Š”๋ฐ AuthenticationException์ธ ์ธ์ฆ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ด ๋งž์„๊นŒ์š”?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forbidden ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๋ณ€๊ฒฝํ•ด์•ผ๊ฒ ๋„ค์š”.

์ด ๋ถ€๋ถ„์—์„œ๋„ ์ด์ชฝ์—์„œ๋„ ์™œ check๋ณด๋‹ค verify๋ฅผ ๊ถŒ์žฅํ•˜๋Š” ์ง€ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ ๊ฐ™๋„ค์š”. AuthorizationDecision ์ธ๊ฐ€ ๊ฒฐ๊ณผ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ์— ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•ด์ฃผ๋Š” ๊ฒƒ์ด ํ•„์š”ํ•ด ๋ณด์ด๋„ค์š”!

Comment on lines 21 to 22
boolean matchURI = Arrays.stream(requestURIs)
.anyMatch(uri -> uri.equalsIgnoreCase(request.getRequestURI()));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์‹ค์ œ spring security์—์„œ๋Š” ์„ฑ๋Šฅ์˜ ๋ฌธ์ œ๋กœ ์ธํ•ด stream ์‚ฌ์šฉ์„ ์ œํ•œํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

spring-projects/spring-security#7154

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์„ฑ๋Šฅ ๋ฌธ์ œ์™€ ๊ฐ€๋…์„ฑ์€ ์–ธ์ œ๋‚˜ ๊ณ ๋ฏผ์ด ๋˜๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.
์š”์ฆ˜์€ ๊ฐœ๋ฐœํ•˜๋ฉด Stream ์„ ๊ฐ€๋…์„ฑ์ด ์กฐ๊ธˆ ๋” ์ข‹๋‹ค๊ณ  ์ƒ๊ฐํ•ด์„œ ์„ ํƒํ•˜๋Š” ๊ฒƒ ๊ฐ™๋„ค์š”.
๋ง์”€ํ•ด์ฃผ์‹  ๋Œ€๋กœ ForEach ๋กœ ์ˆ˜์ •ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!

Comment on lines 22 to 30
if (method.isAnnotationPresent(Secured.class)) {
Secured secured = method.getAnnotation(Secured.class);
boolean hasNoRole = authentication.getAuthorities()
.stream()
.noneMatch(auth -> Arrays.asList(secured.value()).contains(auth));
if (hasNoRole) {
throw new ForbiddenException();
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์งˆ๋ฌธ์ฃผ์‹  ๋‚ด์šฉ์— ๋‹ต๋ณ€ ๋‹ฌ์•„๋‘์—ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ AuthoritiesAuthorizationManager๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ๊นŒ์ง€๋Š” ์•„๋‹ˆ์–ด๋„ ์ธ๊ฐ€๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ AuthorityAuthorizationManager๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณ€๊ฒฝํ•ด๋ณด๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์š”.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ธ๊ฐ€ ๋ถ€๋ถ„์„ ์œ„์ž„ํ•˜๋„๋ก ๋ณ€๊ฒฝํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค!


import java.util.Set;

public class AuthorityAuthorizationManager implements AuthorizationManager<HttpServletRequest> {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public class AuthorityAuthorizationManager implements AuthorizationManager<HttpServletRequest> {
public class AuthorityAuthorizationManager implements AuthorizationManager<T> {

์œ„์—์„œ ๋‚˜์—ดํ•œ ์ด์œ ์—์„œ ์‚ฌ์‹ค HttpServletRequest๋ณด๋‹ค๋Š” ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ํ™œ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ๊ณณ์—์„œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ๋” ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๊ฒ ์ฃ .

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ํ•„ํ„ฐ์™€ ์ธํ„ฐ์…‰ํ„ฐ ํ˜น์€ ์ธํ„ฐ์…‰ํ„ฐ์—์„œ๋„ ์—ฌ๋Ÿฌ ์ข…๋ฅ˜ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ข‹์€ ์„ ํƒ ๊ฐ™์Šต๋‹ˆ๋‹ค,

๊ทธ๋ ‡๋‹ค๋ฉด AuthorityAuthorizationManager ๋Š” ์—ฌ๋Ÿฌ ์ข…๋ฅ˜์˜ ๊ตฌํ˜„์ฒด๋ฅผ ๋งŒ๋“ค์–ด์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ๋„ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด RequestMatcherDelegatingAuthorizationManager ์ฒ˜๋Ÿผ ์—ฌ๋Ÿฌ ๊ตฌํ˜„์ฒด์— support ๋ฉ”์„œ๋“œ๋‚˜ Matcher๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
์ด๋ฅผ ํ†ตํ•ด ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์ธ๊ฐ€ ์ž‘์—…์ธ์ง€ ํ™•์ธํ•˜๊ณ  ๊ทธ์— ๋งž๋Š” AuthorityAuthorizationManager ๊ตฌํ˜„์ฒด๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์‰ฝ๊ฒŒ ๊ด€๋ฆฌ ๋  ๊ฒƒ ๊ฐ™์•„์š”!

import nextstep.security.authentication.Authentication;
import nextstep.security.authorization.AuthorizationDecision;

@FunctionalInterface

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์„ ํƒ์‚ฌํ•ญ์— ๋‚˜์™€์žˆ๋Š” verify๋Š” ๊ตฌํ˜„ํ•˜์ง€ ์•Š์œผ์…”๋„ ๋˜๊ธด ํ•˜์ง€๋งŒ, check์™€ verify๋Š” ๊ฐ๊ฐ ์–ด๋–ค ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉํ•  ํ•ด์•ผ ์ข‹์€์ง€ ์„ธ์ค€๋‹˜์˜ ์˜๊ฒฌ์€ ์–ด๋– ์‹ ๊ฐ€์š”?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ œ๊ฐ€ ์ด ๋ฏธ์…˜์„ ์ง„ํ–‰ํ•˜๋ฉด์„œ ๋А๋‚Œ ์ ์€ ์„ธ ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.

  1. AuthorizationDecision ์˜ ๋„์˜ ์œ„ํ—˜์„ฑ
  2. AuthorizationDecision ๊ฐ€ ์‹คํŒจ๋ฌ์„ ๋•Œ์˜ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์ผ๊ด€์„ฑ
  3. ์‚ฌ์šฉ๋„ ์•ˆํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํ„ด
    ์ด๋Ÿฐ ์ƒํ™ฉ๋•Œ๋ฌธ์— verify๋ฅผ ๊ถŒ์žฅํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
    ํ•˜์ง€๋งŒ AuthorizationDecision ์˜ ๊ฒฐ๊ณผ๋ฅผ ์ปค์Šคํ…€ ์˜ˆ์™ธ๋‚˜ ์กฐ๊ฑด๋ถ€ ๋กœ์ง์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋งŒ check์„ ์‚ฌ์šฉํ•ด ๊ฒฐ๊ณผ๋ฅผ ํ•ธ๋“ค๋ง ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์‚ฌ์‹ค spring security์—์„œ๋Š” verify๋ฅผ ๊ถŒ์žฅํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์—์š”. (์˜คํ•ด์˜ ์†Œ์ง€๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์•„ ๋ฏธ๋ฆฌ ๋ง์”€๋“œ๋ฆฌ๋ฉด ์ •๋‹ต์„ ์š”๊ตฌํ•˜๊ธฐ ์œ„ํ•ด ๋‚จ๊ฒจ๋“œ๋ฆฐ ์งˆ๋ฌธ์€ ์•„๋‹™๋‹ˆ๋‹ค.)

๋ง์”€ํ•ด์ฃผ์‹  ์ด์œ  ์ค‘ ๋จผ์ € 1์— ๋Œ€ํ•ด์„œ ์ด์•ผ๊ธฐํ•˜๋ฉด null ์œ„ํ—˜์„ฑ์„ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ฒƒ์€ ๋งž์ง€๋งŒ AuthorizationDecision์˜ ๋ฐ˜ํ™˜์€ ์ธ๊ฐ€๋จ(true), ์ธ๊ฐ€์•ˆ๋จ(false)๋งŒ ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ธ๊ฐ€ ์ƒํ™ฉ์ด ์—†์Œ์„ ๋‚˜ํƒ€๋‚ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€๋ น @Secured๊ฐ€ ๊ฑธ๋ฆฐ ๊ณณ์ด ์—†์–ด ๊ฒ€์ฆํ•  authorities๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๊ฒ ๋„ค์š”.

	public AuthorizationDecision check(Supplier<Authentication> authentication, MethodInvocation mi) {
		Set<String> authorities = getAuthorities(mi);
		return authorities.isEmpty() ? null : this.authoritiesAuthorizationManager.check(authentication, authorities);
	}

	private Set<String> getAuthorities(MethodInvocation methodInvocation) {
		Method method = methodInvocation.getMethod();
		Object target = methodInvocation.getThis();
		Class<?> targetClass = (target != null) ? target.getClass() : null;
		MethodClassKey cacheKey = new MethodClassKey(method, targetClass);
		return this.cachedAuthorities.computeIfAbsent(cacheKey, (k) -> resolveAuthorities(method, targetClass));
	}

	private Set<String> resolveAuthorities(Method method, Class<?> targetClass) {
		Secured secured = findSecuredAnnotation(method, targetClass);
		return (secured != null) ? Set.of(secured.value()) : Collections.emptySet();
	}

๋‹ค์Œ์œผ๋กœ ์ค‘์š”ํ•œ ๊ฒƒ์€ ์ธ๊ฐ€๋ฅผ ์ฒดํฌํ–ˆ์„๋•Œ ์ธ๊ฐ€๋˜์ง€ ์•Š์€ ์œ ์ €์ธ ๊ฒƒ์ด AuthorizationManager์ž…์žฅ์—์„œ๋Š” ์˜ˆ์™ธ์ƒํ™ฉ์€ ์•„๋‹ ์ˆ˜ ์žˆ๋‹ค์—์š”. ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ฒƒ์€ ์ด ์ƒํ™ฉ์ด ์‹คํŒจํ–ˆ์œผ๋‹ˆ ์‹คํŒจ๋ฅผ ์ „ํŒŒํ•˜๋Š” ๊ฒƒ์ด ๋ชฉ์ ์ผํ…๋ฐ์š”. spring security ์ž…์žฅ์—์„œ๋Š” AuthorizationManager๋Š” ์ธ๊ฐ€๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ด์ฃผ๋Š” ๊ฐ์ฒด์ด๊ณ , ์‹ค์ œ ์—๋Ÿฌ๋Š” AuthorizationFilter ๋“ฑ๊ณผ ๊ฐ™์€ ํ•„ํ„ฐ์—์„œ ์ธ๊ฐ€๊ฐ€ ์•ˆ๋˜์—ˆ๋Š” ์ƒํ™ฉ์„ ํŒ๋‹จํ•˜์—ฌ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ์ฃผ๊ณ  ์žˆ์–ด์š”.

๊ทธ๋ž˜์„œ ๋‚ด๋ถ€์ ์œผ๋ก  ์กฐ๊ธˆ ๋” ๋ณต์žกํ•˜์ง€๋งŒ AuthorizationFilter์—์„œ๋Š” ์ธ๊ฐ€ ๊ฒฐ๊ณผ์— ๋Œ€ํ•œ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœํ–‰ํ•œ ๋‹ค์Œ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ธฐ๋„ ํ•ด์š”.

AuthorizationResult result = this.authorizationManager.authorize(this::getAuthentication, request);
this.eventPublisher.publishAuthorizationEvent(this::getAuthentication, request, result);
if (result != null && !result.isGranted()) {
	throw new AuthorizationDeniedException("Access Denied", result);
}
chain.doFilter(request, response);

spring security์˜ AuthorizationManager๋ฅผ ๋ณด๋ฉด ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ์ฝ”๋“œ๊ฐ€ ์—†๋Š” ๊ฒƒ์„ ๋ณด์‹œ๊ฒŒ ๋ ํ…๋ฐ ๊ทธ๋Ÿฐ ๊ฒƒ๋“ค๋„ ์œ„์™€ ๊ฐ™์€ ์ด์œ ์—์„œ์ผ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ž์„ธํ•œ ์„ค๋ช… ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์ˆœ ์ธ๊ฐ€ ์„ฑ๊ณต, ์‹คํŒจ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์—ฌ๋Ÿฌ ์ผ€์ด์Šค์— ๋Œ€ํ•ด์„œ๋Š” ๊นŠ์ด ์ƒ๊ฐ ๋ชปํ–ˆ์—ˆ๋Š”๋ฐ, ๊ณ ๋ฏผํ•ด๋ณผ ํฌ์ธํŠธ๋„ค์š”!

AuthorizationManager์—์„œ๋Š” ์ธ๊ฐ€ ํ™•์ธ, AuthorizationFilter ์ „์ฒด์ ์ธ ๋งฅ๋ฝ์„ ํŒŒ์•…ํ•˜์—ฌ ํ•„ํ„ฐ๋ง ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๊ตฐ์š”!


@FunctionalInterface
public interface AuthorizationManager<T> {
AuthorizationDecision check(Authentication authentication, T object);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์ตœ๊ทผ spring security ๋ฒ„์ „์—์„œ๋Š” check๋Š” deprecated๋˜์—ˆ์Šต๋‹ˆ๋‹ค. AuthorizationDecision์ด ์ง€๊ธˆ ๋งŒ๋“ค์–ด์ฃผ์‹  ๊ฒƒ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„์ฒด๋กœ ๋˜์–ด์žˆ๊ณ , ์ผ๋ฐ˜์ ์œผ๋กœ ์˜คํ”ˆ์†Œ์Šค๋“ค์ด ์ปค์งˆ์ˆ˜๋ก ๋‹จ์ˆœํ•˜๊ฒŒ ๊ตฌํ˜„ํ•ด๋‘์—ˆ๋˜ ๊ตฌํ˜„์ฒด๋“ค์„ ์ถ”์ƒํ™”ํ•˜๋Š” ํ˜•ํƒœ๋กœ ๊ฐœ์„ ํ•ด๋‚˜๊ฐ€๋Š”๋ฐ์š”.

๊ทธ๋ž˜์„œ ์ตœ๊ทผ ๋ฒ„์ „์—์„œ๋Š” ๊ตฌํ˜„์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” check๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๊ธฐ๋ณด๋‹ค๋Š” deprecatedํ•ด๋‘” ๋’ค ์ด๋ฅผ ์ถ”์ƒํ™”ํ•œ AuthorizationResult๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ํ•ด๋‹น ๋ฉ”์†Œ๋“œ ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

https://github.com/franticticktick/spring-security/blob/main/core/src/main/java/org/springframework/security/authorization/AuthorizationManager.java

spring-projects/spring-security#14712
spring-projects/spring-security#14846

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๋ฏธ์…˜์„ ํ•˜๋‹ค๋ณด๋‹ˆ ๋ง์”€ํ•ด์ฃผ์‹  ๋Œ€๋กœ AuthorizationDecision ๊ฐ€ deprecated๋œ ์ด์œ ๊ฐ€ ๊ฐ„์ ‘์ ์œผ๋กœ ๋А๊ปด์ง€๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
RequestMatcherDelegatingAuthorizationManager ์—์„œ๋„ checkInFilter ๋ณด๋‹ค๋Š” verifyInFilter๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด
AuthorizationFilter ์—์„œ์˜ ์ธ๊ฐ€ ์š”์ฒญ, ์˜ˆ์™ธ์ฒ˜๋ฆฌ ๋‘๊ฐ€์ง€ ์—ญํ• ์—์„œ ์ธ๊ฐ€ ์š”์ฒญ๋งŒ ๋‚จ๊ฒŒ๋˜์–ด์„œ ํ›จ์”ฌ ๊น”๋”ํ•ฉ๋‹ˆ๋‹ค!

MZC01-PARKJUN5 added 6 commits February 12, 2025 15:13
 - String๊ณผ Collection String์„ ์ง€์›ํ•˜๋„๋ก ๋ณ€๊ฒฝ
 - AuthorizationDecision ์˜ ๋„์˜ ์œ„ํ—˜์„ฑ๊ณผ ์‚ฌ์šฉ๋„ ์•ˆํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํ„ดํ•˜๋ฉด์„œ ๊ฒฐ๊ณผ์— ๋Œ€ํ•œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋„ ์ผ๊ด„์„ฑ์„ ๊ฐ€์ง€์ง€ ๋ชปํ•˜๊ธฐ์— verify ๋ฅผ ํ†ตํ•ด ๊ฒ€์ฆ๊นŒ์ง€ ์œ„์ž„
โ€ฆ์ธ๊ฐ€ ์ž‘์—…์„ ์œ„์ž„ํ•˜๋„๋ก ๋ณ€๊ฒฝ

 - SecuredAuthorizationManager ์—์„œ๋Š” Annotation ๊ฐ’์„ ํ†ตํ•œ ๋™์  ์ธ๊ฐ€
 - RequestMatcherDelegatingAuthorizationManager ์—์„œ๋Š” ์ธ๊ฐ€ ์ž‘์—…์„ ํ•˜์ง€ ์•Š์Œ
Copy link

@jinyoungchoi95 jinyoungchoi95 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์•ˆ๋…•ํ•˜์„ธ์š” ์„ธ์ค€๋‹˜ ๐Ÿ˜„

ํ”ผ๋“œ๋ฐฑ ์ž˜ ๋ฐ˜์˜ํ•ด์ฃผ์…จ๋„ค์š” ๐Ÿ‘ ํ•„์š”ํ•œ ๋‚ด์šฉ๋“ค์„ ๋ชจ๋‘ ์ž˜ ํ•™์Šตํ•ด์ฃผ์‹ ๋“ฏํ•˜์—ฌ ๋จธ์ง€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
์„ ํƒ์‚ฌํ•ญ์˜ ๊ฒฝ์šฐ ๋ฏธ์…˜ ์ง„ํ–‰์„ ์›ํ•˜์‹œ๋ฉด ๋ง์”€ํ•ด์ฃผ์‹œ๋ฉด ์ด์–ด์„œ ์ง„ํ–‰ํ•˜๊ณ , ์›ํ•˜์ง€ ์•Š์œผ์‹œ๋ฉด ๋ฏธ์…˜ ์ข…๋ฃŒ์ฒ˜๋ฆฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ถ๊ธˆํ•˜๊ฑฐ๋‚˜ ๊ณ ๋ฏผ์ด ๋˜๋Š” ๋ถ€๋ถ„์ด ์žˆ์œผ์‹œ๋‹ค๋ฉด ์–ธ์ œ๋“  pr ์ฝ”๋ฉ˜ํŠธ ๋˜๋Š” dm์œผ๋กœ ์š”์ฒญ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.
๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ๐Ÿ™‡โ€โ™‚๏ธ

Comment on lines +6 to +9
public class MvcRequestMatcher implements RequestMatcher {

private final HttpMethod httpMethod;
private final String[] requestURIs;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์‹ค์ œ๋กœ๋Š” httpMethod, requestUri๊ฐ๊ฐ ํ•˜๋‚˜๋งŒ์„ ๊ฐ€์ง€๋ฏ€๋กœ String[]์œผ๋กœ ํ‘œํ˜„๋˜์ง„ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฑ ํ•˜๋‚˜๋กœ ์ง€์ •๋œ method, uri๋งŒ์„ ๊ฒ€์ฆํ•˜๋ฉด ๋˜๋Š”๊ฑฐ์ฃ .

์—ฌ๋Ÿฌ๊ฐœ์˜ uri๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋ผ๋ฉด ํ•„์š”ํ•œ ๊ฐ์ฒด๊ฐ€ RequestMatcher๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ๋กœ ๋“ค๊ณ  ์žˆ๋Š” ํ˜•ํƒœ๊ฐ€ ๋” ์ž์—ฐ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ํ•˜๋‚˜์˜ Matcher์— ํ•˜๋‚˜์˜ URI ๊ฒ€์ฆํ•˜๋Š” ๊ฒƒ์ด ๋” ์ดํ•ดํ•˜๊ธฐ ์ข‹๊ฒ ๋„ค์š”!

@@ -0,0 +1,25 @@
package nextstep.security.authorization;

public class AuthorizationDecision {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๋ฏธ์…˜์—์„œ๋Š” spring security์˜ ๊ธฐ๋Šฅ์ด ์ถ•์†Œ๋˜์–ด true, false๊ฐ€ ์ž˜ ์•ˆ์™€๋‹ฟ์œผ์‹ค ์ˆ˜ ์žˆ์œผ๋‚˜ ์‹ค์ œ๋กœ๋Š” ๊ทธ๋ณด๋‹ค ๋” ๋‹ค์–‘ํ•œ ๊ตฌํ˜„์ฒด๋“ค์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

https://github.com/spring-projects/spring-security/blob/main/core/src/main/java/org/springframework/security/authorization/AuthorityAuthorizationDecision.java

@jinyoungchoi95 jinyoungchoi95 merged commit 7a4adfd into next-step:parkjun5 Feb 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants