[Spring Security] anonymous
π μ΅λͺ μ¬μ©μ νν λ°©λ²μ λ³ν
μ΄μ μΈμ¦ μμ€ν
μμλ μΈμ¦λμ§ μλ μ¬μ©μλ₯Ό null
λ‘ νννλ κ²½μ°κ° λ§μλ€. κ·Έλ¬λ μ΄λ μ½λμ user == null
κ³Ό κ°μ μλ§μ κ²μ¦ λ‘μ§ μμ±μ λ°°κ²½μ΄ λμμΌλ©°, NullPointerException
μ νμ κ³ λ €ν΄μΌ νλ€.
μ΄λ¬ν λ¬Έμ λ₯Ό Spring Securityλ βμ‘΄μ¬νμ§ μμβμ΄λΌλ μνλ₯Ό μλ¬΄λ° λμμ νμ§ μμ§λ§ μ€μ κ°μ²΄μΈ AnonymousAuthenticationToken
μΌλ‘ νννλ€.
μΈμ¦λ μ¬μ©μλ
UsernamePasswordAuthenticationToken
μΌλ‘ νμΈνλ€.
μ΄λ₯Ό ν΅ν΄ SecurityContextHolder
κ° νμ Authentication
κ°μ²΄λ₯Ό ν¬ν¨νκ² λλ€. μ¦, μΈμ¦ κ°μ²΄λ₯Ό κ°μ Έμ¬ λ κ·Έ λ¦¬ν΄ κ°μ΄ μ λ null
μ΄ λμ§ μλλ€λ λΆλ³μ±μ 보μ₯νκ² λλ€.
π AnonymousAuthenticationFilter
AnonymousAuthenticationFilter
λ μΈμ¦ λ©μ»€λμ¦ μ΄ν λ€λ₯Έ μΈμ¦ νν°λ€μ΄ μΈμ¦μ μννμ§ λͺ»νμ λ, μ¦ SecurityContext
μ μΈμ¦ κ°μ²΄κ° μ‘΄μ¬νμ§ μλ κ²½μ° λμνλ€. AnonymousAuthenticationFilter
λ SecurityContext
κ° λΉμ΄μλ€λ©΄ AnonymousAuthenticationToken
μ μμ±νμ¬ contextμ μ μ₯νλ€.
1
2
3
4
5
6
7
8
public AnonymousAuthenticationFilter(String key, Object principal, List<GrantedAuthority> authorities) {
Assert.hasLength(key, "key cannot be null or empty");
Assert.notNull(principal, "Anonymous authentication principal must be set");
Assert.notNull(authorities, "Anonymous authorities must be set");
this.key = key;
this.principal = principal;
this.authorities = authorities;
}
μ΄κΈ°μ νν°κ° μμ±λλ©΄ μΈ κ°μ§ μ λ³΄κ° μ€μ λλ€. key
λ AnonymousAuthenticationToken
μ μλ³νλ κ³ μ ν ν€μ΄λ€. principal
μλ μ΄λ€ μ¬μ©μκ° μ‘΄μ¬νλμ§ λͺ
μνλ©°, κΈ°λ³Έκ°μΌλ‘ anonymous
κ° μΈν
λλ€. authorities
μλ μ΅λͺ
μ¬μ©μκ° κ°μ§λ κΆνμ λͺ
μνλ©°, κΈ°λ³Έκ°μΌλ‘ ROLE_ANONYMOUS
λ₯Ό κ°μ§λ€.
1
2
3
4
5
6
7
8
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
Supplier<SecurityContext> deferredContext = this.securityContextHolderStrategy.getDeferredContext();
this.securityContextHolderStrategy
.setDeferredContext(defaultWithAnonymous((HttpServletRequest) req, deferredContext));
chain.doFilter(req, res);
}
μ΄ν μ¬μ©μμ μμ²μ doFilter
λ©μλλ‘ λ€μ΄μ€κ² λλ€. νν°μ ν΅μ¬ λ‘μ§μ defaultWithAnonymous
λ©μλμ μ‘΄μ¬νλ€.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private SecurityContext defaultWithAnonymous(HttpServletRequest request, SecurityContext currentContext) {
Authentication currentAuthentication = currentContext.getAuthentication();
if (currentAuthentication == null) {
Authentication anonymous = createAuthentication(request);
// ...
SecurityContext anonymousContext = this.securityContextHolderStrategy.createEmptyContext();
anonymousContext.setAuthentication(anonymous);
return anonymousContext;
}
else {
// ...
}
return currentContext;
}
λ¨Όμ getAuthentication
λ©μλλ₯Ό ν΅ν΄ SecurityContext
μ μ΄λ―Έ Authentication
κ°μ²΄κ° μ‘΄μ¬νλμ§ νμΈνλ€. μμ νν°λ€μ΄ μ΄λ―Έ μ¬μ©μλ₯Ό μΈμ¦νλμ§ νμΈνκ² μν΄μμ΄λ€. λ§μ½ μ‘΄μ¬νλ€λ©΄ νν°λ μλ¬΄λ° λμμ μννμ§ μκ³ λμ΄κ°λ€.
λ§μ½ μ‘΄μ¬νμ§ μλλ€λ©΄, μ¦ ν΄λΉ μ¬μ©μκ° μΈμ¦λμ§ μμλ€λ©΄ createAuthentication
λ©μλλ₯Ό νΈμΆνμ¬ AnonymousAuthenticationToken
μ μμ±νλ€,
1
2
3
4
5
6
protected Authentication createAuthentication(HttpServletRequest request) {
AnonymousAuthenticationToken token = new AnonymousAuthenticationToken(this.key, this.principal,
this.authorities);
token.setDetails(this.authenticationDetailsSource.buildDetails(request));
return token;
}
νν°μ μμ±μμμ μ€μ λ key
, principal
, authorities
λ₯Ό ν΅ν΄ ν ν°μ μμ±νκ³ λ€λ₯Έ μΈλΆ μ 보λ€μ ν ν°μ μΆκ°ν ν λ§λ€μ΄μ§ ν ν°μ 리ν΄νλ€.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private SecurityContext defaultWithAnonymous(HttpServletRequest request, SecurityContext currentContext) {
Authentication currentAuthentication = currentContext.getAuthentication();
if (currentAuthentication == null) {
// ...
SecurityContext anonymousContext = this.securityContextHolderStrategy.createEmptyContext();
anonymousContext.setAuthentication(anonymous);
return anonymousContext;
}
else {
// ...
}
return currentContext;
}
μ΄ν ν ν°μ λ£μ SecurityContext
λ₯Ό μμ±ν ν ν ν°μ λ£λλ€. μ΄λ κ² μμ±λ SecurityContext
λ₯Ό 리ν΄νμ¬ νμ¬ μμ²μ SecuritContextHolder
μ μ€μ λλ€.
π AnonymousAuthenticationToken
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// AnonymousAuthenticationFilter.java
protected Authentication createAuthentication(HttpServletRequest request) {
AnonymousAuthenticationToken token = new AnonymousAuthenticationToken(this.key, this.principal,
this.authorities);
token.setDetails(this.authenticationDetailsSource.buildDetails(request));
return token;
}
private AnonymousAuthenticationToken(Integer keyHash, Object principal,
Collection<? extends GrantedAuthority> authorities) {
super(authorities);
Assert.isTrue(principal != null && !"".equals(principal), "principal cannot be null or empty");
Assert.notEmpty(authorities, "authorities cannot be null or empty");
this.keyHash = keyHash;
this.principal = principal;
setAuthenticated(true);
}
νν°μ λͺ
μλ key
, principal
, authorities
λ₯Ό μΈν
νκ³ , authenticated
νλλ₯Ό μ€μ νλ€. μ΄ νλμ κ°μ true
λ‘ μ€μ λλλ°, μ΄λ μ¬μ©μκ° μ±κ³΅μ μΌλ‘ λ‘κ·ΈμΈνμλ€λ μλ―Έκ° μλλΌ ν΄λΉ Authentication
κ°μ²΄κ° Spring Securityκ° μ λ’°νλ μ ν¨ν κ°μ²΄λΌλ κ²μ μλ―Ένλ€.
1
2
3
public Object getCredentials() {
return "";
}
ν ν°μ credentials
μλ λΉ λ¬Έμμ΄μ΄ μΈν
λλλ°, μ΄λ μ¦λͺ
ν μ격 μ¦λͺ
μ΄ μμμ μλ―Ένλ€.
π μ£Όμμ¬ν λ° νΉμ§
μ΅λͺ μ¬μ©μμκ² κ³Όλν κΆνμ λΆμ¬νμ§ μλλ‘ νλ€. λΉμ°ν λΆλΆμ΄κΈ΄ νλ€. μΈμ¦λ μ¬μ©μμμ κ²½κ³λ₯Ό λͺ νν ν΄μΌ νλ€.
AnonymousAuthenticationToken
μ μ΅μνμ μ λ³΄λ§ λ³΄κ΄νλ―λ‘ λ©λͺ¨λ¦¬μ μΌλ‘ ν¨μ¨μ μ΄λ€. λν ν ν°μ΄ μΈμ
μμ κ΄λ¦¬λμ§ μμΌλ―λ‘ μΈμ
곡κ°μ μ°¨μ§νμ§ μλλ€.
μ΅λͺ
μ¬μ©μ κ΄λ ¨ μ²λ¦¬λ instanceof
λ authorities
λ₯Ό νμΈμΌλ‘ κ°λ¨ν μ΄λ£¨μ΄μ§ μ μλ€.