Springboot/Security

[Spring Security]

이영애님 2020. 1. 18. 13:28

 

스프링시큐리티 헤더 default

- 캐시금지, 스니프 방지, HSTS, 프레임옵션, XSS공격 방지

 

Authentication - 인증. 유저증명

Authorization - 인가. 권한결정

 


 

  • SecurityContextHolder, to provide access to the SecurityContext.
  • SecurityContext, to hold the Authentication and possibly request-specific security information.
  • Authentication, to represent the principal in a Spring Security-specific manner.
  • UserDetails, to provide the necessary information to build an Authentication object from your application’s DAOs or other source of security data. (principal)
  • UserDetailsService, to create a UserDetails when passed in a String-based username (or certificate ID or the like).
  • GrantedAuthority, to reflect the application-wide permissions granted to a principal. (권한객체)

 

** UsernamePasswordAuthenticationToken - instance of the Authentication interface

** UserDetailsService - DB에서 유저의 정보를 가져와서 리턴 (in-memory map, JDBC) 


[권한객체]

	static final List<GrantedAuthority> AUTHORITIES = new ArrayList<GrantedAuthority>();

	static {
		AUTHORITIES.add(new SimpleGrantedAuthority("ROLE_USER"));
	}

 

 

[로그인]

try {
	Authentication request = new UsernamePasswordAuthenticationToken(name, password);
	Authentication result = am.authenticate(request);
	SecurityContextHolder.getContext().setAuthentication(result);
} catch (AuthenticationException e) {
	System.out.println("Authentication failed: " + e.getMessage());
}

System.out.println("Successfully authenticated. Security context contains: "
				+ SecurityContextHolder.getContext().getAuthentication());
		
		/*
		 * Successfully authenticated. Security context contains: \
		 * org.springframework.security.authentication.
		 * UsernamePasswordAuthenticationToken@441d0230: \ Principal: bob; Password:
		 * [PROTECTED]; \ Authenticated: true; Details: null; \ Granted Authorities:
		 * ROLE_USER
		 */
...

class SampleAuthenticationManager implements AuthenticationManager {
	public Authentication authenticate(Authentication auth) throws AuthenticationException {
		if (auth.getName().equals(auth.getCredentials())) {
			return new UsernamePasswordAuthenticationToken(auth.getName(), auth.getCredentials(), AUTHORITIES);
		}
		throw new BadCredentialsException("Bad Credentials");
	}
}

 

  1. The username and password are obtained and combined into an UsernamePasswordAuthenticationToken
  2. The token is passed to an instance of AuthenticationManager for validation.
  3. The AuthenticationManager returns a fully populated Authentication instance on successful authentication.
  4. The security context is established by calling SecurityContextHolder.getContext().setAuthentication(…​), passing in the returned authentication object.

 

[로그인 사용자 정보 얻기]

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

if (principal instanceof UserDetails) {
	String username = ((UserDetails)principal).getUsername();
} else {
	String username = principal.toString();
}


혹은 UserDetailsService

UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;

[springSecurityFilterChain]

 

SecurityContextPersistenceFilter

-  stores the context as an HttpSession attribute between HTTP requests

restores the context to the SecurityContextHolder for each request

-  clears the SecurityContextHolder when the request completes

 

ExceptionTranslationFilter

- detecting any Spring Security exceptions that are thrown

- returning error code 403

-  launching an AuthenticationEntryPoint (if the principal has not been authenticated)


 

[Authentication]

 

AuthenticationManager 

 

AuthenticationEntryPoint

- As you’re not presently authenticated, the server sends back a response indicating that you must authenticate. 

- Each major authentication system will have its own AuthenticationEntryPoint implementation


[Authorization]

 

Security interceptors and the "secure object" model

 

AccessDecisionManager


[CSRF]

Synchronizer Token 

- ensure that each HTTP request requires, in addition to our session cookie, a secure random generated value called a CSRF token must be present in the HTTP request.

- server must look up the expected CSRF token and compare it against the actual CSRF token in the HTTP request

 

<!> CSRF token should be in a part of the HTTP request

- HTTP request that is not automatically included by the browser

- cookies are automatically included in the HTTP request by the browser.

 

** CSRF Token is automatically included by Thymeleaf.

 


Access Currently Authenticated User

SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
String username = authentication.getName();
Object principal = authentication.getPrincipal();
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();

** https://docs.spring.io/spring-security/site/docs/5.3.0.M1/reference/htmlsingle/#authentication-password-storage-history