Java/Spring Boot

Spring Security Java Config

ddss6565 2023. 7. 16. 00:39

@Slf4j, @Getter, @Setter 는 Lombok 어노테이션임.

 

SpringSecurityConfig.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter
{
    @Autowired
    private LoginService loginService;

    @Autowired
    private LoginSuccessHandler loginSuccessHandler;

    @Autowired
    private LoginFailHandler loginFailHandler;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.userDetailsService(loginService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http.authorizeRequests().antMatchers("/login").permitAll();
        http.authorizeRequests().anyRequest().hasAnyRole("ADMIN, USER");

        // successHandler, defaultSuccessUrl 한 개만 설정
        // failureHandler, failureUrl  한 개만 설정

        http.formLogin()
            .loginPage("/login")
            .loginProcessingUrl("/login")
            .usernameParameter("username")
            .passwordParameter("password")
            .successHandler(loginSuccessHandler)
            .defaultSuccessUrl("/", true)
            .failureHandler(loginFailHandler)
            .failureUrl("/login");
        http.logout()
    		.logoutUrl("/logout")
            .invalidateHttpSession(true);

        http.csrf().disable();
        http.headers().frameOptions().disable();
        http.sessionManagement().maximumSessions(1).expiredUrl("/logout");
    }

    @Bean
    public PasswordEncoder passwordEncoder()
    {
        return new BCryptPasswordEncoder();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception
    {
        return super.authenticationManagerBean();
    }

    @Override
    public void configure(WebSecurity web) throws Exception
    {
        web.ignoring()
            .antMatchers("/static/**")
            .antMatchers("/login/**")
            .antMatchers("/logout/**")
            .antMatchers("/error/**");
    }
}

SecurityWebInitializer.java

public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer
{

}

# 로그인 프로세스

LoginService.java

@Slf4j
@Service
public class CmmLoginService implements UserDetailsService
{
    @Autowired
    private UserInfoMapper userInfoMapper;
    
    @Override
    public UserDetails loadUserByUsername(String username)
    {
        CmmLoginUser user = new CmmLoginUser();
        user.setUserId(username);
        user = userInfoMapper.selectUser(user);
        
        user.setUsername(username);
        user.setPassword(user.getUserPassword());
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        user.setAuthorities(authorities);
        
        return user;
    }
}

# 사용자 객체

LoginUser.java

@Getter
@Setter
public class CmmLoginUser extends CmmLoginService implements UserDetails, Serializable
{
    private static final long serialVersionUID = 1L;
    
    private String username;
    private String password;
    
    private boolean isEnabled = true;
    private boolean isNonExpired = true;
    private boolean isNonLocked = true;
    private boolean isCredentialsNonExpired = true;
    
    public void setAuthority(String authority)
    {
        authorities.add(new SimpleGrantedAuthority(authority));
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities()
    {
        return authorities;
    }

    @Override
    public boolean isAccountNonExpired()
    {
        return isNonExpired;
    }

    @Override
    public boolean isAccountNonLocked()
    {
        return isNonLocked;
    }
}

# 로그인 성공 추가 작업

LoginSuccessHandler.java

@Slf4j
@Service
public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler
{
    @Autowired
    private LoginService loginService;
    
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException
    {
    
    }
}

# 로그인 실패 추가 작업

LoginFailHandler.java

@Slf4j
@Service
public class LoginFailHandler implements AuthenticationFailureHandler
{
    @Autowired
    private LoginService loginService;
    
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException
    {
        
    }
}
반응형