인가와 인증
확인된 순간 > 인증된 유저 > 그 후 정보를 보내줄때 인가 처리하고 보냄
스프링 시큐리티에서 인가는 사용자가 특정 자원에 접근할 수 있는 권한을 부여하는 것을 의미한다. 인증된 사용자는 특정 권한을 부여받은 후에만 자원에 접근할 수 있다. 이는 사용자가 로그인하여 인증을 받는 순간부터 시작된다. 인증된 사용자는 이후 요청할 때마다 인가 처리가 되어 필요한 정보에 접근할 수 있게 된다.
스프링 시큐리티
스프링 시큐리티는 인증과 인가를 모두 처리하는 프레임워크이다. 이는 필터 체인을 기반으로 동작하며, 요청이 필터 체인을 통과할 때 인증과 인가가 처리된다. 필터 체인은 다양한 보안 관련 필터들이 순차적으로 적용되는 구조로 되어 있다.
Principal과 Credential
Principal은 주체, 즉 누가 인증을 요청하는지를 나타낸다. Credential은 신원 증명 정보로, 비밀번호나 주민등록번호, 토큰 값 등이 이에 해당한다. Principal과 Credential을 통해 사용자의 신원을 확인하고 권한을 부여할 수 있다.
RestController
RestController는 RESTful 웹 서비스에서 주로 사용하는 컨트롤러로, HTTP 요청의 본문에 데이터를 담아 전달받는다. 주로 JSON 형식으로 데이터를 주고받으며, 클라이언트와 서버 간의 데이터 통신을 처리한다.
추상화와 DI (Dependency Injection)
추상화는 구체적인 구현을 숨기고 인터페이스나 추상 클래스를 통해 시스템을 설계하는 방법이다. 이를 통해 시스템은 더 유연하고 확장 가능해진다. DI는 의존성 주입으로, 역할을 가진 객체를 외부에서 주입함으로써 객체 간의 결합도를 낮추고, 느슨한 의존을 가능하게 한다.
package com.springboot.config;
import com.springboot.member.InMemoryMemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.method.P;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.provisioning.UserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.formLogin()
//로그인을 실제 사용할 주소
.loginPage("/auths/login-form")
.loginProcessingUrl("/process_login")
//실제 로그인이 실패하면 나올 주소
.failureUrl("/auths/login-form?error")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/")
.and()
//권한이 없는 특정 사용자가 접근했을때 이걸 보여주겠다
.exceptionHandling().accessDeniedPage("/auths/access-denied")
.and()
.authorizeHttpRequests(authorize -> authorize
//순서 중요함
.antMatchers("/orders/**").hasRole("ADMIN")
.antMatchers("/members/my-page").hasRole("USER")
//* 하나면 조회만 , ** 두개면 depth 2까지 허용
.antMatchers("/**").permitAll());
return http.build();
}
@Bean
public UserDetailsManager userDetailsManager() {
//UserDetailsManager는 인터페이스고 추상화 되어있다.
UserDetails user =
User.withDefaultPasswordEncoder()
.username("luckykim@google.com")
.password("qwerty123")
.roles("USER")
.build();
UserDetails admin =
User.withDefaultPasswordEncoder()
.username("admin@google.com")
.password("1111")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
//메서드 명으로 등록됨
}
@Bean
public PasswordEncoder passwordEncoder(){
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
}
권한 관리
사용자의 권한은 GrantedAuthority 인터페이스를 통해 관리된다. 개개인의 권한을 조회하여 요소로 갖는 리스트를 반환하는 메서드 예제는 다음과 같다:
private List<GrantedAuthority> createAuthorities(String... roles) {
// List<GrantedAuthority> 개개인의 권한을 조회해서 요소로 갖는다는 것
// 이거의 반환값인 new SimpleGrantedAuthority(role))권한을 갖고 있는 객체를 받음
// 근데 왜 리스트로 권한을 받을까? 한 유저가 하나의 롤만 가지지않음,
// 즉 인가 처리할 때 여러가지 롤을 받을 수있기 때문에 리스트로 받는게 기본임
return Arrays.stream(roles)
.map(role -> new SimpleGrantedAuthority(role))
.collect(Collectors.toList());
}
이는 여러 가지 역할을 가진 사용자를 지원하기 위해 리스트로 권한을 관리하는 것이다. 한 사용자가 여러 가지 롤을 가질 수 있기 때문에 리스트로 관리하는 것이 기본이다.
@ElementCollection(fetch = FetchType.EAGER)
private List<String> roles = new ArrayList<>();
'spring > [Spring Security] 기본' 카테고리의 다른 글
| 사용하는 용어 정리 (0) | 2024.08.03 |
|---|---|
| 요청처리 (0) | 2024.07.05 |
| Cookie (0) | 2024.07.03 |
| Hashing (0) | 2024.07.03 |
| 인증/보안 (0) | 2024.07.03 |