Spring-Boot/etc.

SpringBoot - Spring Security

PHM 2022. 5. 6. 10:13

config - WebSecurityConfig.java

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	// 패스워드 인코더
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Override
    protected void configure(HttpSecurity http) throws  Exception{
        http
            .csrf().disable()   // jwt토큰 방식을 쓰기에 필요한 설정
            
            .authorizeRequests()                                        // HttpServletRequest를 사용하는 요청들에 대한 접근제한을 설정
                .antMatchers("/joinMember","loginMember").permitAll()   // 해당요청은 인증없이 접근허용
                .anyRequest().authenticated()                           // 나머지 요청들은 인증받아야함
                
            // 다른 페이지로 가면 로그인페이지로 자동 리다이렉트
            .and()
            .formLogin()
            .loginPage("/login")
            .usernameParameter("m_id")
            .passwordParameter("m_pw")
            .loginProcessingUrl("/loginMember")   // /loginMember 주소가 호출이 되면 시큐리티가 낚아채서 대신 로그인을 진행

 

config - auth - PrincipalDetails

- 시큐리티가 loginProcessingUrl인 /loginMember 주소 요청이 오면 낚아채서 로그인 진행 진행

- 로그인을 진행이 완료가 되면 시큐리티 session을 만들어준다. ( Security ContextHolder )

- 오브젝트 => Authentication 타입 객체

- Authentication 안에 user 정보가 있어야 함

- user 오브젝트타입 => UserDetails 타입 객체

- Security Session => Authentication => UserDetails(PrincipalDetails_

@Data
public class PrincipalDetails implements UserDetails,OAuth2User {

    private memberVO mem;
    private Map<String,Object> attributes;

    // 일반로그인
    public PrincipalDetails(memberVO mem) {
        this.mem = mem;
    }
    
    // OAuth로그인
    public PrincipalDetails(memberVO mem, Map<String, Object> attributes) {
        this.mem = mem;
        this.attributes = attributes;
    }
    
    // 해당 User의 권한을 리턴하는 곳곳
   @Override
    public Collection<? extends GrantedAuthority> getAuthorities(){
        Collection<GrantedAuthority> collet = new ArrayList<>();
        collet.add(new GrantedAuthority() {
            @Override
            public String getAuthority() {
                return mem.getM_role();
            }
        });
        return collet;
   };

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

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

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

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

    @Override
    public boolean isCredentialsNonExpired(){
        return true;
    };

    @Override
    public boolean isEnabled(){
        // 사이트에서 1년동안 회원이 로그인을 안하면 휴면계정
        // mem.getLoginDate()
        // 현재 시간 - 로그인시간 => 1년을 초과하면 return false;
        return true;
    };

    @Override
    public Map<String, Object> getAttributes() {
        return attributes;
    }

    @Override
    public String getName() {
        return null;
    }
}

config - auth - PrincipalDetailsService

- 시큐리티 설정에서 loginProcessingUrl("/login")

- /login 요청이 오면 자동으로 UserDetailService타입으로 IoC되어있는 loadUserByUsername함수가 실행

- 시큐리티 session => Authentication => UserDetails => Authentication(내부 UserDetails) => 시큐리티 session

@Service
public class PrincipalDetailsService implements UserDetailsService {
    @Autowired
    private memberMapper memberMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println(11111);
        memberVO user = memberMapper.selectId(username);

        if(user != null){
            System.out.println(11111);
            return new PrincipalDetails(user);
        }

        return null;
    }
}

 

 

참고자료

: https://blog.naver.com/getinthere/222064999924

https://www.youtube.com/watch?v=6n4k8Van_HI&list=PL93mKxaRDidERCyMaobSLkvSPzYtIk0Ah&index=4

 


Springboot + Spring Security + React를 시도하였으나 .loginProcessingUrl를 이용한 방법은 SpringBoot의 폼태그가 있는 클라이언트 페이지와 Action값을 따라가는 것 같음. React를 연동해보았으나 계속 PrincipalDetailsService를 찾지 못함.

-> 예제를 찾아봐도 거의 다 Spring Security + React는 JWT 방법을 씀, 그래서 JWT 방법으로 변경


2022-06-09

.loginProcessingUrl를 이용한 해결방법

- react에서 spring으로 데이터를 보낼때 데이터 형식을 Content-Type: application/json 형태로 보냄.

- form 태그의 형식은 Content-Type: application/x-www-form-urlencoded 사용함

- 적용은 안해봤지만 아마 될 것으로 예상...