SpringBoot Security
Last updated
Was this helpful?
Last updated
Was this helpful?
우리가 원하는대로 유연하게 커스텀하는 것이 가능하다!
설정하기 위해서는 pom.xml에서 spring-boot-starter-security 라는 의존성을 추가해줘야한다
AuthenticationManager bean을 등록해준다. 그러면 default로 메모리에 하나의 사용자를 등록시켜준다(user라는 이름, pw는 콘솔창에 뜨게 된다)
static resource은 자동으로 무시한다 = 보안이 필요 없다
다양한 특징들을 활성화시켜준다. - XSS, CSRF 등등
저렇게 pom.xml에 추가만 해줘도 자동으로 인증절차를 밟아야만 웹페이지에 접근할 수 있도록 바뀌게된다 ⇒ default로 만들어진 user/콘솔에있는 비밀번호 이걸 가지고 로그인을 하면 정상적으로 접속하는것이 가능하다
만약 다른 사용자를 넣어주고 싶다면 application.properties에서
= 사용자이름
spring.security.user.password = 사용자비밀번호
spring.security.user.roles = USER, ADMIN
이거같은 경우에는 굳이 ROLE_USER이렇게 안해도 괜찮은게 어짜피 자동적으로 앞에 ROLE_ 이 붙게 되어있다!
하지만 이런 설정들은 따로 db에 설정해주지 않았을경우에 따로 만들어준 경우이다
WebMvcConfigure라는 interface를 implements한 WebConfig라는 클래스를 만들고, addViewControllers을 오버라이딩 해줘야한다. 안에는 ViewControllerRegistry registry.addViewController("/").setViewName("home");
pox.xml에 thymleaf-extras-springsecurity5 추가!
이렇게 해주면 일반 컨트롤러에서 RequestMapping("/")에다가 return "home"하는 함수와 같은 역할을 해준다 = 코드가 줄어든다!
SpringSecurityDialect을 bean으로 등록시켜줘야함
SpringSecurityDialect란? thymeleaf의 extra module이고, Spring MVC와 thymeleaf을 통합해주는역할을 한다.
thymeleaf에서 권한이 있을때를 확인하는 방법은
sec:authorize = "hasRole('USER')" : 권한이 통과되면 출력해주는
sec:authentication="이름이나 권한" : 이름이나 권한을 출력해주는
Role-based access control using a database
UserDetailsService to get UserDetails from database → loadUserByUsername()을 통해서 service에 있는 값들을 UserDetails에다가 넣어준다!
Customized Spring Security Configuration
pom.xml에다가 spring-boot-starter-data-jpa을 넣어주고, mysql-connector-java 을 넣어줘야함
application.properties에다가 DataSource에 대한 세팅을 해주고, JPA에 대한 세팅을 해주고, 로깅도 해주고
사용자의 request가 오게되면 AuthenticationFilter를 거친다
AuthenticationFilter를 거치면서 생긴 토큰을 AuthenticationManager에게 건내주고
AuthenticationManager는 AuthenticationProvider(db와 연관되어있는)에게 건내게된다.
AuthenticationProvider는 PasswordEncoder와 UserDetailsService와 연관이 되어있다.
사용자가 로그인했을때 PasswordEncoder를 거치면, 해쉬된 값을 나오게된다
여기서 PasswordEncoder를 빈으로 등록을 해주고, 그 안에서 BCryptPasswordEncoder()을 사용한다! ⇒ 밑에 Spring Security Configuration 설정시
UserDetailService에는 loadUserByUserName()이 있어서 loadUserByUserName()이 DB를 거쳐서 UserDetails를 가지고 온다
AuthenticationProvider가 UserDetailService를 사용하고 있고, UserDetailsService가 loadUserByUserName()을 사용해서 데이터베이스에서 객체를 꺼내온다.
여기서 UserDetailService를 마음대로 커스터마이즈해서 활용하면 된다!
@Configuration, @EnableWebSecurity이 들어가고
WebSecurityConfigurerAdapter를 상속받는 클래스를 만든다.
만든 클래스는 Spring Security에 관한 설정들이 들어가는 클래스이다
전에 만들었던 커스텀 UserDetailsService를 @Autowired로 가져와주고, PasswordEncoder(BCryptPasswordEncoder)을 빈으로 등록해주고,
configureGlobal(AuthenticationManagerBuilder auth)로 위의 UserDetailsService와 PasswordEncoder를 등록해준다
random number인 salt을 이용해서 hash password을 만들어 낸다.
$기준으로 나누고
2a : BCrypt 알고리즘 버전
10 : 알고리즘의 강도
16글자 : 랜덤으로 만들어진 16it의 salt번호
남은것 : plain text(31글자)
plaintext는 PasswordEncoder encoder.encode("원하는문자")
이렇게 넣어서 만드러냄
configure라는 클래스안에 매개변수로 HttpSecurity http로 선언하고
http.authorizeRequests()
.antMatchers("url").permitAll()
.antMatchers("url").hasRole("ROLE")
.anyRequest().authenticated()
.and()로 다음껄로 이어줌
http.formLogin()
.loginPage("")
.defaultSuccessUrl("")
.failureUrl("")
.permitAll()
.and()로 다음껄로 이어줌
logout()
logoutRequestMatcher()
.logoutSuccessUrl()
.permitAll()
.and()
sec:authorize = "isAuthenticated()"
만약 인증된 사용자가 접근시, 표시해줌
sec:authorize = "isAnonymous()"
인증되지 않은 사용자가 접근시 표시
sec:authorize = "hasRole('ROLE_USER')"
ROLE_USER라는 권한을 가진 사람에게 표시
CSRF을 방지하기 위해서는 기본으로 enable()되어있기 때문에 만약에 테스트를 위해서 열어보고싶다면 HttpSecurity http.csrf().disable(); 을 통해서 열수 잇음
CSRF token을 request시 함께 보내서 악의적인 공격이 아님을 알려야하는데, 원래 자동으로 form태그에 들어가있게된다
만들어야하는 것들
RegistrationService Interface
RegistrationServiceImpl Class
RegistrationController Class
Signup.html