본문 바로가기

bitcamp/면접족보

면접족보_21/02/19

1. emp 테이블을 스프링 시큐리티에서 커스텀마이징 하시오.

· xml에서는 username, password, enabled 세 가지 정보만 가져올 수 있기 때문에 커스텀마이징을 통해 확장하여
  JSP에서 session 객체를 통해 다른 정보를 가져온다.  · 
· EmpDetailsService 객체를 생성하여 로그인 하는 경우, Service의 loadUserByUsername을 호출한다.

 

<security-custom-context.xml>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
     <http auto-config="true" use-expressions="true">
        <intercept-url pattern="/login/loginForm" access="permitAll" />
        <intercept-url pattern="/" access="permitAll" />
        <intercept-url pattern="/admin/**" access="hasRole('ADMIN')" />
        <intercept-url pattern="/**" access="hasAnyRole('USER', 'ADMIN')" />
      
      <!-- 로그인 페이지 커스텀 화, 로그인 성공 시 / 이동, 실패 시 /login/loginForm?error 이동 -->
      <form-login login-page="/login/loginForm"
                    default-target-url="/"
                    authentication-failure-url="/login/loginForm?error"
                    username-parameter="id"
                    password-parameter="password" />
      
      <logout logout-url="/logout" logout-success-url="/" /> 
                
      <!-- 403 에러 처리 -->
      <access-denied-handler error-page="/login/accessDenied"/>      
   </http> 
      
    <beans:bean id="bcryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />       
 
    <beans:bean id="customNoOpPasswordEncoder" class="edu.bit.ex.security.CustomNoOpPasswordEncoder"/>
    <beans:bean id="empDetailsService"   class="edu.bit.ex.security.EmpDetailsService" />  
 
   <authentication-manager>
      <authentication-provider user-service-ref="empDetailsService">
         <password-encoder ref="customNoOpPasswordEncoder"/>      
      </authentication-provider>
   </authentication-manager>    
</beans:beans>
cs

 

<HomeController.java>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Log4j
@Controller
public class HomeController {
 
   @RequestMapping(value = "/", method = RequestMethod.GET)
   public String home(Locale locale, Model model) {
      log.info("Welcome home! The client locale is {}.");
      return "home";
   }
 
   @GetMapping("/user/userHome")
   public void userHome() {
      log.info("userHome ...");      
   }
 
   @GetMapping("/admin/adminHome")
   public void adminHome() {
      log.info("adminHome ...");
   }
   
   @GetMapping("/login/accessDenied")
   public void accessDenied(Model model) {
      log.info("Welcome Access Denied!");
   }
   
   @GetMapping("/login/loginForm")
   public String loginForm() {
      log.info("Welcome Login Form!");
      return "login/loginForm2";
   }
}
cs

 

<home.jsp>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 <body>
    <h1>메인페이지</h1>
 
    <sec:authorize access="isAnonymous()">
       <p><a href="<c:url value="/login/loginForm" />">로그인</a></p>
    </sec:authorize>
 
    <sec:authorize access="isAuthenticated()">
        <form:form action="${pageContext.request.contextPath}/logout" method="POST">
       <input type="submit" value="로그아웃" />
        </form:form>
           <p><a href="<c:url value="/loginInfo" />">로그인 정보 확인 방법3 가지</a></p>
    </sec:authorize>
 
    <h3>
        [<a href="<c:url value="/user/userForm" />">회원가입</a>]
        [<a href="<c:url value="/user/userHome" />">유저 홈</a>]
        [<a href="<c:url value="/admin/adminHome" />">관리자 홈</a>]
    </h3>
 </body>
cs

 

<EmpVO.java>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Log4j
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class EmpVO {
   String empno;   
   String ename;  
   String job;
   int mgr;
   Timestamp hiredate;  
   int sal;
   int comm;
   int deptno;
   String authority; //권한
}
cs

 

<EmpMapper.java>

1
2
3
4
@Mapper
public interface EmpMapper {
   EmpVO getEmp(String ename);
}
cs

 

<EmpMapper.xml>

1
2
3
4
5
6
7
 <mapper namespace="edu.bit.ex.mapper.EmpMapper">
    <select id="getEmp" resultType="edu.bit.ex.vo.EmpVO">
        <![CDATA[
    select ename, empno, job, mgr, hiredate, sal, comm, deptno, case when job='MANAGER' then 'ROLE_ADMIN' else 'ROLE_USER' end as authority from emp where ename = #{ename} 
        ]]>
    </select>
 </mapper>
cs

 

<EmpDetailsService.java>

· UserDetails 타입으로 리턴 하기 위해 그에 맞는 타입으로 변환!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Log4j
@Service
public class EmpDetailsService implements UserDetailsService  {
   
   @Setter(onMethod_ = @Autowired)
   private EmpMapper empMapper;
   
   @Override
   public UserDetails loadUserByUsername(String ename) throws UsernameNotFoundException {
      
      log.warn("Load User By EmpVO number: " + ename);      
      EmpVO vo = empMapper.getEmp(ename);   
      
      log.warn("queried by EmpVO mapper: " + vo);
      
      return vo == null ? null : new EmpUser(vo);
   }
}
cs

 

<EmpUser.java>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Setter
@Getter
@ToString
public class EmpUser extends User {
    private EmpVO emp;
 
    // 기본적으로 부모의 생성자를 호출해야만 정상적으로 작동
    public EmpUser(String username, String password, Collection<extends GrantedAuthority> authorities) {
        super(username, password, authorities);
    }
 
    public EmpUser(EmpVO empVO) {
        super(empVO.getEname(), empVO.getEmpno(), getAuthority(empVO));
        this.emp = empVO;
    }
 
    // 유저가 갖고 있는 권한 목록
    public static Collection<extends GrantedAuthority> getAuthority(EmpVO empVO) {
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.add(new SimpleGrantedAuthority(empVO.getAuthority()));
 
        return authorities;
    }
 }
cs

 

<userHome.jsp>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 <html lang="ko">
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 <title>유저 페이지</title>
 </head>
 <body>
    <h1>유저 페이지 입니다.</h1>
    <p>principal: <sec:authentication property="principal"/></p>
    <p>사용자이름: <sec:authentication property="principal.emp.ename"/></p>
    <p>사용자월급: <sec:authentication property="principal.emp.sal"/></p>
    <p>사용자입사일자: <sec:authentication property="principal.emp.hiredate"/></p> 
    <p><a href="<c:url value="/" />"></a></p>
 </body>
 </html>
cs

 

 

<로그인 전/후>

<유저 홈, emp 정보 출력 화면>