스프링 시큐러티

최지혜·2022년 10월 9일
0

spring

목록 보기
3/4

시큐러티 들어가기 전에, 컨트롤러 만들기.

@Controller
public class HomeController {
	
    @GetMapping(/"Hello")
    public String hello() {
    	return  "Hello";
    }
}

테스트 코드는

@RunWith(SpringRunner.class)
@WebMvcTest(HomeController.class)
public class HomeControllerTest {
	@autowired
    MockMvc mockMvc;
    
    @Test
    public void hello() throws Exception {
    	mockMvc.perform(get("/hello"))
        		.andDo(print())
                .andExpect(status().isOK())
                .andExpect(view().name("Hello"));
    }
}

시큐리티를 xml 파일에 추가

<dependency>
	<groupId>org.springframework.boot</groupId>
  	<artifactId>spring-boot-starter-security</artifactId>
</dependency>

모든 요청이 스프링시큐러티로 인해 인증이 필요하게 됨.
베이직어센티케이션이(컨텐츠 타입이 아니라, 어셉트 헤더에 따라 달라짐- 이 응답을 브라우저 받으면 브라우저는 브라우저가 내장하고 있는 안 이쁜 베이직어센티케이션폼을 띄우게 되어 있음.)

@Configuration
@ConditionalOnClass(DefaultAuthenticationEventPublisher.class)
@EnableConfigurationProperties(SecurityProperties.class)
@Import({SpringBootWebSecurityConfiguration.class, Web~})
puvlic class SecurityAutoConfiguration {
	@Bean
	@Conditional IOnMissingBean(uthenticationEventPublisher.class)
    public DefaultAuthenticationEventPublisher authenticationEventPublisher(ApplicationEventPublisher publisher) {
		retuern new DefaultAuthenticationEventPublisher(publisher); 
    }
}

이벤트에 핸들러 등록해서 유저의 상태를 변경하는 등 여러가지를 할 수 있음.

  • 모든 요청에 인증 필요해짐.
  • 인증 관련 각종 이벤트 발생 -디폴트어쎈시케이션이벤트퍼블리셔빈등록, 다양한 인증 에러 핸들러 등록 기능
  • 기본 사용자를 스프링부트가 생성해줌.(Usename, Password)
  • 스프링부트가 해주는 것: 유저디테일 서비스가 없을 때, 어센티케이션 프로바이더가 없는 경우에만 인메모리로 유저디테일즈매니저를 만들어서 랜덤하게 유저를 생성해줌.
    대게는 유저디테일 서비스를 등록해주기 때문에, 스프링부트가 지원하는 시큐리티 관련 기능은 쓸 일이 별로 없음.

  • 테스트 할 때는
    @WithMockUser
    어노테이션 붙여주면 가짜유저 등록해서 테스트 해줌.
    -> 이 클래스 안에 들어있는 모든 메소드 테스트 가능.

스프링 시큐리티 설정 커스터마이징

1. 웹시큐리티 설정

@Configuration
public class WebSecurityConfig extents WebSecurityConfigurerAdapter {
	@Override
    protected void configure(HJttpSecurity http) throws Exception {
    	http.authorizeRequests()
        	.antMatchers("/", "/hello").permitAll()
            .anyRequest().authenticated()
            .and()
        .formLogin()
        	.and()
        .httpBasic();
    }
}

2. UserDetailsServiece 구현

보통 서비스계층에 인터페이스 구현

@Service
public class AccountService implements UserDetailsService {
	@Autowired
    private AccountRepository accountRepository
    ...
   
}
  • implements UserDetailsService 있어야만 스프링부트가 맘대로 유저 생성 안 함. UserDetailsService를 이용해서 로그인 처리가 되는 것.

  • 로그인 처리를 할 때 loadUserByUsername이 호출이 됨.
    로그인할 때 아이디, 패스워드 등록하면 그 정보가 여기로 옴. username에 해당하는 실제 user정보(안에 password가 들어있음, 같으면 로그인, 다르면 예외 던짐.)를 확인함.

핵심 인터페이스

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundE {
	Optional<Account> nyusername = accountRepository.findByUsername(username);
    //유저를 가져옴.
	byUsername.orElseThrow(() -> new UsernamedNotFoundException(username));
    //데이터가 없으면
    //UserDetails는 핵심적 유저의 중요정보 담은 인터페이스
    //이 인터페이스의 기본 구현체를 스프링시큐리티가 유저라는 이름으로 제공을 함. 어카운트 정보(계정 정보)를 유저디테일즈로 변환해서 리턴!
    return new User(account.getUsername(), account.getPassword(), authorities());
    //이렇게 하면 어쏘리티스 메소드를 밑에 만들어 줘야함.
}
private Collection<? extends GrantedAuthority> authorities() {
	return Arrays.asList(new SimpleCrantedAuthority("ROLE_USER"));
}

3. PasswordEncorder 설정 및 사용

profile
매일 성장하는 개발자

0개의 댓글