1. security 패키지 및 하위 클래스 생성
- CustomAccessDeniedHandler.java
package works.yermi.security;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
public class CustomAccessDeniedHandler implements AccessDeniedHandler{
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
throw accessDeniedException;
}
}
- CustomUserDetailsService.java
package works.yermi.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import lombok.Setter;
import lombok.extern.log4j.Log4j;
import works.yermi.domain.CustomUser;
import works.yermi.domain.MemberVO;
import works.yermi.mapper.MemberMapper;
@Log4j
public class CustomUserDetailsService implements UserDetailsService {
@Autowired @Setter
private MemberMapper mapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// TODO Auto-generated method stub
log.warn(username);
MemberVO vo = mapper.read(username);
return vo == null ? null : new CustomUser(vo);
}
}
2. config 내 security 관련 클래스 생성
- SecurityConfig.java
package works.yermi.config;
// import 생략
@Configuration
@EnableWebSecurity
@AllArgsConstructor // 생성자 주입
public class SecurityConfig extends WebSecurityConfigurerAdapter{
private DataSource dataSource;
@Override // http 대체
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().loginPage("/member/login").loginProcessingUrl("/login");
http.logout().logoutUrl("/logout").logoutSuccessUrl("/");
http.rememberMe().tokenRepository(persistentTokenRepository());
}
@Override // authentication-provider 대체
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
}
@Bean // password-encoder 빈 등록
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public UserDetailsService userDetailsService() {
return new CustomUserDetailsService();
}
@Bean
public AccessDeniedHandler accessDeniedHandler() {
return new CustomAccessDeniedHandler();
}
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl impl = new JdbcTokenRepositoryImpl();
impl.setDataSource(dataSource);
return impl;
}
}
- Securityinitializer.java
package works.yermi.config;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class Securityinitializer extends AbstractSecurityWebApplicationInitializer{
}
3. WebConfig, ServletConfig에 SecurityConfig 추가
- WebConfig.java
package works.yermi.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer{
@Override
protected Class<?>[] getRootConfigClasses() { // SecurityConfig.class 추가
// TODO Auto-generated method stub
return new Class[] {RootConfig.class, SecurityConfig.class};
}
// 이하 생략
}
- ServletConfig.java
package works.yermi.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan("works.yermi.controller")
@EnableGlobalMethodSecurity(prePostEnabled=true) // 추가
public class ServletConfig implements WebMvcConfigurer{
// 생략
}
- 403 에러 해결하기
- 비동기 처리 403 에러
- 외부 API 사용에 따른 403 에러