ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SpringBoot - Spring Security
    Spring-Boot/etc. 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 사용함

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

    댓글

Designed by Tistory.