스프링 부트 기초 - 9(SpringSecurity 다시 보기)

2 minute read

스프링 시큐리티 설정

▶ SecurityConfig

@Configuration // 빈등록(IoC관리)
@EnableWebSecurity // 시큐리티 필터가 등록이 된다.
@EnableGlobalMethodSecurity(prePostEnabled = true) // 특정 주소로 접근을 하면 권한 및 인증을 미리 체크 하겠다는 뜻
public class SecurityConfig extends WebSecurityConfigurerAdapter{

@Override
protected void configure(HttpSecurity http) throws Exception {
	http
		.csrf().disable() // csrf 토큰 비활성화(테스트시 걸우두는게 좋음)
		.authorizeRequests()
			.antMatchers("/", "/auth/**", "/js/**", "/css/**", "/image/**")
			.permitAll()
			.anyRequest()
			.authenticated()
		.and()
			.formLogin()
			.loginPage("/auth/loginForm")
			.loginProcessingUrl("/auth/loginProc") // 스프링 시큐리티가 해당 주소로 요청오는 로그인을 가로챈다. 대신 로그인 해준다.
			.defaultSuccessUrl("/");	// 정상적으로 로그인이 되면 여기로 이동
	}
}


비밀번호 해쉬화 하기(암호화)

▶ SecurityConfig

@Configuration // 빈등록(IoC관리)
@EnableWebSecurity // 시큐리티 필터가 등록이 된다.
@EnableGlobalMethodSecurity(prePostEnabled = true) // 특정 주소로 접근을 하면 권한 및 인증을 미리 체크 하겠다는 뜻
public class SecurityConfig extends WebSecurityConfigurerAdapter{

	@Bean
	public BCryptPasswordEncoder endcodePWD() {
		return new BCryptPasswordEncoder();
	}
}
  • BCryptPasswordEncoder 객체를 Bean 으로 등록

▶ UserService

@Autowired
private BCryptPasswordEncoder encoder;

@Transactional
public void 회원가입(User user) {
	String rawPassword = user.getPassword(); // 1234 원래 비밀번호
	String encPassword = encoder.encode(rawPassword); // 해쉬화
	user.setPassword(encPassword); // 해쉬화 된 패스워드로 셋
	user.setRole(RoleType.USER);
	userRepository.save(user);
}


스프링 시큐리티로 로그인 하기

▶ SecurityConfig

@Configuration // 빈등록(IoC관리)
@EnableWebSecurity // 시큐리티 필터가 등록이 된다.
@EnableGlobalMethodSecurity(prePostEnabled = true) // 특정 주소로 접근을 하면 권한 및 인증을 미리 체크 하겠다는 뜻
public class SecurityConfig extends WebSecurityConfigurerAdapter{

	// 시큐리티가 대신 로그인해주는데 password를 가로채기 하는데
	// 해당 password가 뭘로 해쉬가 되어 회원가입이 되었는지 알아야
	// 같은 해쉬로 암호화해서 DB에 있는 해쉬랑 비교할 수 있음.
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(principalDetailService).passwordEncoder(endcodePWD());
	}

	@Bean
	public BCryptPasswordEncoder endcodePWD() {
		return new BCryptPasswordEncoder();
	}
}


▶ PrincipalDetail

@Getter
public class PrincipalDetail implements UserDetails{

	private User user; // 컴포지션

	public PrincipalDetail(User user) {
		this.user = user;
	}

	@Override
	public String getPassword() {
		return user.getPassword();
	}

	@Override
	public String getUsername() {
		return user.getUsername();
	}

	// 계정이 만료되지 않았는지 리턴한다.(true : 만료 안됨)
	@Override
	public boolean isAccountNonExpired() {
		return true;
	}

	// 계정이 잠겨있지 않았는지 리턴한다.(true : 잠기지 않음)
	@Override
	public boolean isAccountNonLocked() {
		return true;
	}

	// 비밀번호가 만료되지 않았는지 리턴. (true : 만료안됨)
	@Override
	public boolean isCredentialsNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}

	// 계정이 활성화(사용가능)인지 리턴한다. (true : 활성화)
	@Override
	public boolean isEnabled() {
		// TODO Auto-generated method stub
		return true;
	}

	// 계정이 갖고있는 권한 목록을 리턴한다. (권한이 여러개 있을 수 있어서 루프를 돌아야 하는데 우리는 한개만)
	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {

		Collection<GrantedAuthority> collectors = new ArrayList<>();
		collectors.add(() -> {return "ROLE_" + user.getRole();});

//		collectors.add(new GrantedAuthority () {
//			public String getAuthority() {
//				return "ROLE_" + user.getRole();	// ROLE_USER -> ROLE 꼭 붙여주기
//			}
//		});

		return collectors;
	}
}

UserDetails를 implements 하여 사용한다


UserDetails

Security에서 사용자의 정보를 담는 인터페이스가 UserDetails 인터페이스이다.

이 인터페이스를 구현하게 되면 이제 Security 인증, 인가 관련 작업에서 우리가 구현한 인터페이스를 기준으로 작업하게 될 것이다.



스프링 시큐리티(현재 사용자 조회)

@AuthenticationPrincipal 어노테이션을 활용해 현재의 로그인 정보를 얻어 온다

@PostMapping(value = "/api/board")
public ResponseDto<Integer> save(@RequestBody Board board, @AuthenticationPrincipal PrincipalDetail principal) {// title, content
	boardService.글쓰기(board, principal.getUser());	// principal.getUser()는 현재 세션의 아이디를 의미
	return new ResponseDto<Integer>(HttpStatus.OK.value(),1);
}

📑 출처

Categories:

Updated:

Leave a comment