반응형

*로그인 세션정보 가져오는 절차
1. post 요청으로 signin 하면

@EnableWebSecurity
@Configuration //IOC
public class SecurityConfig extends WebSecurityConfigurerAdapter {

   ...
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable(); //csrf 비활성화
        http.authorizeRequests()
                .antMatchers("/", "/user/**", "/image/**", "/subscribe/**", "/comment/**").authenticated() //인증이 필요한 url
                .anyRequest().permitAll() //어떤 요청이라도 허용.
                .and()
                .formLogin()
                .loginPage("/auth/signin")
                .loginProcessingUrl("/auth/signin") //스프링 시큐리티가 로그인 프로세스 진행           
                .defaultSuccessUrl("/"); //로그인 정상됐을때 이동하는 url
    }

}

 

2. 서버에 도달하기 전에 시큐리티가 로그인 정보를 낚아챈다.
   시큐리티는 PrincipalDetailService(UserDetailsService를 상속받음)에게 로그인 정보를 넘긴다.

   - .loginProcessingUrl("/auth/signin") 가 있으면 로그인 요청으로 인식하고
     원래라면 UserDetailsService가 낚아채야하지만 PrincipalDetailsService가 UserDetailsService를 상속 받기때문에         여기서 대신 낚아챔
   - 패스워드는 알아서 체킹하니가 신경x
   - 리턴이 잘되면 자동으로 UserDetails 타입을 세션으로 만든다.
   - 여기서 리턴하는 PrincipalDetails는 UserDetails를 상속받는다(같은 타입이다.).

@RequiredArgsConstructor
@Service
public class PrincipalDetailsService implements UserDetailsService {

    private final UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        User userEntity = userRepository.findByUsername(username);

        if(userEntity == null){
            return null;
        }else{
            //PrincipalDetails 은 UserDetails을 상속
            return new PrincipalDetails(userEntity);
        }
    }
}
@Data
public class PrincipalDetails implements UserDetails {

    private static final long serialVersionUID = 1L;

    private User user;

    public PrincipalDetails(User user){
        this.user = user;
    }
    //권한이 1개가 이닐수 있어서 Collection타입
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {

        Collection<GrantedAuthority> collector = new ArrayList<>(); //ArrayList의 부모가 Collection
        collector.add(() -> { return user.getRole();});
        return collector;
    }

   ...
}

 

@Controller
public class UserController {

    ...
    @GetMapping({"/user/{id}/update"})
    public String update(@PathVariable int id, @AuthenticationPrincipal PrincipalDetails principalDetails, Model model){

        //principal: 인증주체, 인증된 사람의 오브젝트명
        model.addAttribute("principal", principalDetails.getUser());
        return "user/update";
    }
}

 @AuthenticationPrincipal 어노테이션은
로그인 정보, 즉, Authetication 객체에 바로 접근할 수 있다. 

스프링 시큐리티로 로그인하면 Authentication 객체 내부에 Principaldetails가 담긴다.

다음으로 model에다 principalDetails에 담긴 유저정보를 가져와서 프론트단(수정화면)에 뿌려주면 된다. 

+ Recent posts