주의 스프링부트 버전 2.7.8버전이 아니면 오류가 발생할수있음
SecurityConfigure
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.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
// 빈 등록 : 스프링 컨테이너에서 객체를 관리할 수 있게 하는 것
@Configuration //빈등록 (IoC관리)
@EnableWebSecurity //security 필터 등록
@EnableGlobalMethodSecurity(prePostEnabled = true) //특정 주소를 접근을 하면 권한 및 인증을 미리 체크하겠다는 뜻
public class SecurityConfigure {
@Bean
public AuthenticationManager authenticationManager(
AuthenticationConfiguration authenticationConfiguration
) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean // IoC가 됨
public BCryptPasswordEncoder encodePWD() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable() // csrf 토큰 비활성 (테스트시 걸어두는게 좋음)
.authorizeRequests()
.antMatchers("/", "/blog","/auth/**", "/js/**", "/css/**", "/image/**", "/dummy/**", "/board/{id}")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/auth/loginForm")
.loginProcessingUrl("/auth/loginProc")
.defaultSuccessUrl("/"); // 스프링 시큐리티가 해당 주소로 요청오는 로그인을 가로채서 대신 로그인 해준다.
return http.build();
}
}
PrincipalDetail
import java.util.ArrayList;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.cos.blog.model.User;
import lombok.Getter;
//스프링 시큐리티가 로그인 요청을 가로채서 로그인을 진행하고 완료가 되면 UserDetails 타입의 오브젝트를
//스프링 시큐리티의 고유한 세션저장소에 저장을 해준다
@Getter //private에 있는 user는 원래같으면 Class외부에서 접근할수없다 하지만 @Getter어노테이션을 사용하면 접근할수있다
public class PrincipalDetail implements UserDetails {
private User user; //PrincipalDetail은 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() {
return true;
}
//계정이 활성화(사용가능)인지 리턴한다(true:활성화)
@Override
public boolean isEnabled() {
return true;
}
public void setUser(User user) {
this.user = user;
}
//계정이 갖고있는 권한 목록을 리턴한다.(원래는 권한이여러개있을수있으므로 for문을돌리지만 우리는하나만하겠다)
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> collectors = new ArrayList<>();
collectors.add(()->{return "ROLE_"+user.getRole();}); //람다식으로 표현한다 GrantedAuthority에는 한개의 메소드밖께없어서
//자바에서 알잘딱깔센으로 해준다
return collectors;
}
}
PrincipalDetailService
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 org.springframework.stereotype.Service;
import com.cos.blog.model.User;
import com.cos.blog.repository.UserRepository;
@Service
public class PrincipalDetailService implements UserDetailsService{
@Autowired
private UserRepository userRepository;
//스프링이 로그인 요청을 가로챌때 username,password 변수 2개를 가로채는데
//password부분처리는 알아서함
//그래서 아래코드에서 username이 DB에 있는지 확인해줌
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User principal = userRepository.findByUsername(username)
.orElseThrow(()->{
return new UsernameNotFoundException("해당 사용자를 찾을 수 없습니다:"+username);
});
// TODO Auto-generated method stub
return new PrincipalDetail(principal); //이떄 시큐리티의 세션에 유저정보가 저장이된다
}
}
세션이 인증되었는지 확인방법
<sec:authorize access="isAuthenticated()">
<sec:authentication property="principal" var="principal"/>
</sec:authorize>
'나혼자개발' 카테고리의 다른 글
[spring] AOP예시코드 (1) | 2024.10.06 |
---|---|
만들예정 화면 (0) | 2024.07.11 |
ResponseDto에 들어갈 코드 (0) | 2024.07.08 |
javascript+jquery로 데이터보낼때 예시 (0) | 2024.07.08 |
내가만든 블로그 (0) | 2024.07.07 |