본문 바로가기

Web/Spring

Spring Security녀석을 만났다.

728x90
반응형

이번 글은 Spring Security녀석에 대해 얘기 해보겠다.(나도 잘 모른다.)

 

일단 Spring Security는 Spring에서 제공하는 기능이다. 당연한 소리다.

쉽게 그냥 본인이 느낀대로 설명하면 Spring에서 제공하는 로그인기능인 거 같다.

오늘은 정말 간단히만 알아보겠다...왜냐면 나도 잘 모르겠다 아직...

 

SecurityController 로그인 페이지 맵핑 ->


WebSecurityConfig(로그인url) ->

여러가지 권한 설정

@Override
protected void configure(HttpSecurity http) throws Exception {
   http
      .headers()
         .frameOptions().sameOrigin() //Spring Security 는 디폴트로 iframe 사용을 막고 있다. 동일한 도메인일 경우 허용하도록 설정.
         .and()
      .csrf()
         .disable()
      .authorizeRequests()
         .antMatchers("/**").permitAll()
         .antMatchers("/*/main.do").permitAll()
         .antMatchers("/error").permitAll()
         .antMatchers("/mater/**").hasRole("ADMIN")
         .antMatchers("/admin/**").hasRole("ADMIN")
         .antMatchers("/common/member/**").permitAll()
         .antMatchers(ADMIN_LOGIN_PAGE).permitAll()
         .anyRequest().permitAll()
         .and()
      .formLogin()
         .usernameParameter(USERNAME_PARAM_NAME)
         .passwordParameter(PASSWORD_PARAM_NAME)
               .loginPage(WebSecurityUrlConfig.LOGIN_PAGE).permitAll()
               .loginProcessingUrl(WebSecurityUrlConfig.LOGIN_PROCESS_URL).permitAll()
               .successHandler(new CustomLoginSuccessHandler())
               .failureHandler(new CustomLoginFailureHandler())
               .and()
           .logout()
               .logoutUrl("/logout")
               .invalidateHttpSession(true)
               .deleteCookies("JSESSIONID")
               .logoutSuccessHandler(new CustomLogoutSuccessHandler())
               .permitAll()
               .and()
           .exceptionHandling()
               .authenticationEntryPoint(loginUrlAuthenticationEntryPoint)
               .accessDeniedHandler(new CustomAccessDeniedHandler())
               .and()
           .sessionManagement()
               .and()
        ;
}

CustomAuthenticationProvider (권한, 메뉴 셋팅) ->

로그인 한 유저가 사용자 혹은 관리자 여부에 따라 권한 및 접근 가능 메뉴 셋팅

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
   String memberId = authentication.getName();
   UserInfo user = null;
   UserInfo muser = null;
   user = (UserInfo) loginService.loadUserByUsername(memberId);
   String password = authentication.getCredentials().toString();
   if(user == null) {
      throw new BadCredentialsException(messageSource.getMessage("fail.common.login", null, Locale.getDefault()));
   }else if(!passwordEncoder.matches(password, user.getPassword())){
      throw new BadCredentialsException(messageSource.getMessage("fail.common.pwd.diffrent", null, Locale.getDefault()));
   }

   List<GrantedAuthority> userAuthorities = new ArrayList<GrantedAuthority>();

   String mbName ="";

   //기본 role 을 세팅
   if(user.getMbType().equals("M")){
      muser = (UserInfo) loginService.masterInfo(user.getMbCd());
      System.err.println(muser.getManagerSeq());
      System.err.println("muser ::: " + muser);
      loginService.uptMbrAcsRec(user.getMbCd());
      user.setName(muser.getName());
      user.setAuthGroupSeq(muser.getAuthGroupSeq());
      user.setManagerSeq(muser.getManagerSeq());
      userAuthorities.add((GrantedAuthority)new SimpleGrantedAuthority("ROLE_ADMIN"));   //로그인어드민
      user.setAuthorities(userAuthorities);
      
      if("0".equals(muser.getUseYn())) {
         throw new BadCredentialsException(messageSource.getMessage("fail.common.login", null, Locale.getDefault()));
      }

      //권한별 메뉴 세팅
      user.getAllowedMenuMap().put(WebSecurityConfig.MASTER_MENU, menuLoaderService.setUserMenu(user));

   }
   else if(user.getMbType().equals("U")){
      mbName = user.getName();
      userAuthorities.add((GrantedAuthority)new SimpleGrantedAuthority("ROLE_USER"));    //로그인유저
      userAuthorities.add((GrantedAuthority)new SimpleGrantedAuthority("ROLE_USER_" + user.getMbType()));//유저 타입
      user.setAuthorities(userAuthorities);
   }else{
      throw new BadCredentialsException(messageSource.getMessage("fail.common.login", null, Locale.getDefault()));
   }
   return new UsernamePasswordAuthenticationToken(user, "", user.getAuthorities());
}

CustomLoginSuccessHandler(로그인 성공 url)  

사용자 혹은 관리자 여부에 따라 redirect

@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
    HttpSession session = request.getSession();
    process1(request, response, session);
    String reqUrl = session.getAttribute("reqUrl") == null ? null : String.valueOf(session.getAttribute("reqUrl"));
    session.removeAttribute("reqUrl");
    if(reqUrl != null && reqUrl.length() > 0) {
        response.sendRedirect(reqUrl);
    } else {
        if(Util.getUserInfo().getMbType().equals("M")) {
            response.sendRedirect("/master/main.do");
        } else {
            response.sendRedirect("/front/main/main.do");
        }
    }

}

CustomAccessDeniedHandler(접근제어처리)  

@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException {
    log.error("access denied handler");
    response.setContentType("text/html; charset=UTF-8");
    response.setStatus(HttpStatus.UNAUTHORIZED.value());
    e.printStackTrace();
    boolean ajaxFlag = false;
    if("XMLHttpRequest".equals(request.getHeader("x-requested-with"))){
        ajaxFlag = true;
    }
    if(ajaxFlag) {
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    } else {
        UserInfo user = Util.getUserInfo();
        if (user == null) {
            response.sendRedirect("/common/login.do");
        } else {
            PrintWriter out = response.getWriter();
            out.println("<script language='javascript' type='text/javascript'>alert('로그인이 필요합니다.');location.href='" + WebSecurityUrlConfig.LOGIN_PAGE + "'}</script>");
        }
    }
}

CustomLoginFailuerHandler(로그인 실패 url)

로그인 실패 시에 alert 띄우기


@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
    String referrer = request.getHeader("Referer");

    String uLogin = "/common/login.do";
    String mLogin = "/master/login.do";

    exception.printStackTrace();
    System.out.println("로그인 실패");
    String loginFailMessage = exception.getMessage();
    response.setContentType("text/html; charset=UTF-8");
    PrintWriter out = response.getWriter();
    if(referrer.contains(uLogin)){
        out.println("<script language='javascript' type='text/javascript'>alert('"+loginFailMessage+"');location.href='/common/login.do';</script>");
    }else if(referrer.contains(mLogin)){
        out.println("<script language='javascript' type='text/javascript'>alert('"+loginFailMessage+"');location.href='/master/login.do';</script>");
    }
    out.flush();
}

 대충 이런식인 거 같은데...

 

아직 정말 잘 모르겠다 일단 이해한 건 여기까지이다.

 

한 번 잘 알아두면 Spring framework를 사용하는 프로젝트에선 매번 유용하게 사용될 거 같다.

강의도 듣고 공부를 조금 더 해봐야겠다.

 

728x90
반응형

'Web > Spring' 카테고리의 다른 글

맨땅에 Spring Batch - Meta Table  (0) 2024.01.16
맨땅에 Spring Batch - 설정  (0) 2024.01.16
맨땅에 Spring Batch  (0) 2024.01.16
Spring boot에서 mybatis mapper location 설정  (0) 2022.10.25
스프링 스케쥴러란 녀석을 만났다.  (0) 2022.07.27