BE study 14th

 Spring Security


SpringSecurity And Servlet

There's a layer called filter in the spring. When the spring receives a http request, the request goes through 'filter's before going into the servlet. Since one filter calls the next filter, the filters are called.


Spring Security is used as a form of filter. To be specific, it's implemented in a set of filters called 'SecurityFilterChain'.

1. Authentication

Authentication is done like above.

ExceptionTranslationFilter

As you can see in the above image, ExceptionTranslationFilter invokes the rest of the filter chain(FilterSecurityInterceptor etc). And if the user is not authenticated, or rest of the filter calls 'AuthenticationException' Error, it calls its method 'startAuthenticaion'. the method

1. clears out the ContextHolder

2. backups the original HttpServletRequest

3. authenticationEntryPoint.commence() : This is the requested to the client for his/her credentials.

3-1. BasicAuthenticationEntryPoint: This is used in case of Basic Authentication; it uses WWW-Authenticate in response, so that the client can attach its authentication in his/her next request.

3-2. LoginUrlAuthenticationPoint: This one redirects to the sign-in page.

3-3. Http403ForbiddenEntryPoint: This one does not request the client to autheticate. It just responses the 403 error.

 

ExceptionTranslationFilter can handle not only AuthenticationException but also AccessDeniedException. This exception occurs when access is denied, for such reason like the user does not have required permission.

There's AccessDeniedHandler and its implementation Impl, the Impl will redirect to 403 page, or response directly: Json string when RESTFul Server.

securitycontextholder

Just like the above image, SecurityContextHolder has SecurityContext and SecurityContext has Principal, Credentials, and Authorities: Principal represents who you are(like your name), Credentials proves who you are(like your face or fingerprint) and Authorities means what you are permitted to(can you read confidentials? or top secrets?)

So, in the above startAuthentication process, how the things are created? It is done by AbstractAuthenticationProcessingFilter. In case of 3-2. LoginUrlAuthenticationPoint, UsernamePasswordAuthenticationFilter(subclass of AAPF) does it.

1. the client submits the form of sign-in page

2. UsernamePasswordAuthenticationFilter creates a UsernamePasswordAuthenticationToken by submitted form: the token is a type of Authentication.

3. the token is passed into AuthenticationManager
  -most commonly used AuthenticationManager's Impl is 'ProviderManager', which is a chain of 'AuthenticationProvider's. Most commonly used 'AuthenticationProvider' is 'DaoAuthenticationProvider' which usesUserDetailsService and PasswordEncoder to authenticate a username and password.



4. if the manager assesses it to be successful,
1. SessionAuthenticationStrategy is notified of a new sign-in
2. the token is set to the context and the context is set to the holder: in this case, the isAuthenticated() of the token is set True
3. RememberMeServices.loginSuccess is invoked: This is used to send cookies to front-end browsers
4. ApplicationEventPublisher publishes an InteractiveAuthenticationSuccessEvent
5. AuthenticationSuccessHandler is invoked. in case 3-2, it's usually SimpleUrl AuthenticationSuccessHandler which just redirects to the initial request(backupped by startAuthentication())




2. Authorization


Authorization is done by the 'FilterSecurityInterceptor' like it's written above; The FilterSecurityInterceptor is now replaced by 'AuthorizationFilter' but it's still usable. It works like

1. It constructs an instance of 'Supplier' to retrieve the Authentication from the SecurityContextHolder

2. Supplier<Authentication> and HttpServletRequest are passed to AuthorizationManager. The manager matches the request to the patterns '.authorizeHttpRequests()' of the securityConfig. Then, runs the corresponding rules.

    For example,

http

.authorizeHttpRequests((authorize) -> authorize

.requestMatchers("/endpoint").hasAuthority("USER") .anyRequest().authenticated() )

.anyRequest().authenticated()

)

 

the above code means that if the request is /endpoint, then require the USER authority; else, only require authentication

3. If access is granted, an AuthorizationGrantedEvent is published and the rest of the FilterChain is continued.



@Configuration
@EnableWebSecurity 
public class SecurityConfig 
@Bean 
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception 

    http 
   .csrf(Customizer.withDefaults()) 
   .authorizeHttpRequests(authorize -> authorize .anyRequest().authenticated() ) 
   .httpBasic(Customizer.withDefaults()) 
   .formLogin(Customizer.withDefaults()); 

    return http.build(); 
 } 
}

The filters are configured in such way. In the code like above, 
1. CSRFFilter would be invoked to avoid CSRF attack
2. Basic and FormLogin(UsernamePassword) AuthenticationFilters would be invoked
3. AuthroizationFilter would be invoked.
#AuthorizationFilter is always the last of the SecurityFilterChain.

댓글

이 블로그의 인기 게시물

Interface of Java

Data Analytics Overview(OLTP vs OLAP)

Leetcode