공부/Spring

인증(Authentication)

Egomi 2017. 4. 6. 17:24

인증(Authentication)


- spring의 사용자 인증  


@security-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
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
   xmlns="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
       http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd                
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security.xsd">
 
    <!-- 해당 패턴에 접근할 때 ROLE_USER 그룹만 접근가능하게 하라 -->
   <http auto-config="true"<!-- 로그인 창을 알아서 마련하려면 auto-config="true"하면 자동 생성 -->
      <intercept-url pattern="/customer/notice" access="ROLE_USER" />
   </http>
 
   <authentication-manager>
      <authentication-provider>
          <!-- 같은 그룹의 권한(여기선 위의 ROLE_USER)을 갖는 사람만 접근 가능하다. -->
         <user-service>
            <user name="test" password="test" authorities="ROLE_USER" />
            <user name="TJSAL" password="12345" authorities="ROLE_USER" />            
         </user-service>
      </authentication-provider>
   </authentication-manager>
</beans:beans>
cs

기존 JSP에선 인증을 위해 request.getSession 해서 각 페이지마다 로그인 정보를 검사하는 아주 귀찮은 짓을 했다.


Spring에선 AOP를 이용해 자동으로 검사하게 만들 수 있다.


Security-Context를 설정하자.(인증 관련 지시서다.)


@Security-Context

http 태그 내의 intercept-url은 해당 패턴의 url요청을 받을 때마다 ROLE_USER라는 그룹에 속한 사람인지 아닌지 확인하게 된다.


ROLE_USER는 아래 <user-service>의 <user>들 에게 권한을 줄 수 있다. 


지금은 name과 password를 직접 부여했지만, DB를 연동할 수도 있다.


- DB 연동해보기

@security-context.xml

1
2
3
4
5
6
7
8
9
10
   <authentication-manager>
      <authentication-provider>
          <jdbc-user-service data-source-ref="dataSource"
          users-by-username-query="SELECT ID userid, PWD password,
           1 enabled FROM MEMBER WHERE ID=?"
          authorities-by-username-query="SELECT ID userid, 'ROLE_USER' authorities
           FROM MEMBER WHERE ID=?"
          />
      </authentication-provider>
   </authentication-manager>
cs

dataSource에 참고할 Bean을 적어준다. 여기서 Bean은 DB를 연동해주는 역할을 하는데, 다음과 같이 작성했다.

user-by-username-query는 입력받은 username로 DB에서 정보를 가져온다
authorities-by-username-query는 사용자의 권한(비회원, 회원, 관리자 등)을 가져온다.



@Service-context.xml

1
2
3
4
5
6
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
       <property name="driverClassName"  value="com.mysql.jdbc.Driver"/>
       <property name="url" value="jdbc:mysql://211.238.142.84/newlecture?autoReconnect=true&amp;useSSL=false&amp;characterEncoding=UTF-8"/>
       <property name="username" value="newlec" />
       <property name="password" value="sclass"/>
    </bean>
cs


드라이버와 url 등의 DB 연결 정보를 이용해 DB를 가져온다.


- 사용자 인증 전/후 페이지 이동 경로


@login.jsp


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    <form action="${root }/j_spring_security_check" method="POST">
    
        <fieldset>
            <table>
                <c:if test="${not empty validate && not validate}">
                <tr>
                    <td colspan="2" style="color:red;">유효하지 않는 아이디, 비밀번호 입니다.</td>
                </tr>
                </c:if>
                <tr>
                    <th>아이디 :</th>
                    <td><input name="j_username" type="text"/></td>
                </tr>
                <tr>
                    <th>비밀번호 :</th>
                    <td><input name="j_password" type="password"/></td>
                </tr>
                <tr>
                    <td><input type="submit" value="로그인"/></td>
                </tr>
            </table>
        </fieldset>
    </form>
cs


로그인의 경우를 우선 살펴보자. 


jsp폼에서 Spring의 로그인 확인하는 곳으로 액션을 취해준다.



@security-context.xml


1
2
3
4
5
6
7
8
9
    <beans:bean id="successHandler" class="com.newlecture.web.handler.NewlecSuccessHandler">
    </beans:bean>
 
   <http>
      <form-login login-page="/joinus/login" default-target-url="/index"
      authentication-success-handler-ref="successHandler"/>
      <logout logout-success-url="/index"/> <!-- 로그아웃 후 이동할 경로 --> 
      <intercept-url pattern="/customer/notice" access="ROLE_USER" />
   </http>





cs



<http>태그를 위의 bean이 없다고 가정하고 들여다보자.

intercept-url에 notice가 있다. notice로 접근 시 요놈이 가로채 login 페이지로 이동시켜준다.

notice가 아닌 다른 페이지에서 로그인할 경우, default-target-url로 이동시켜준다.

 

로그인 폼에 정보를 입력하고 포스트 했다고 가정하자.

DB에서 사용자 id, pwd, 권한 등 인증 정보 확인 후에는 위의 핸들러에게 인증 정보를 전달해준다.

<beans:bean>의 태그 안에서, 접근 권한에 따라 핸들러가 권한에 맞는 페이지로 이동시켜주게 된다.



로그아웃의 경우 jsp페이지에서 프로젝트명/j_spring_security_logout으로 이동하면 자동으로 해준다.(세션 만료 안해도 돼서 편하다.) 



- jsp에 인증 정보 가져오기

인증정보는 기본적으로 pageContext객체에 저장된다. 객체 내에 저장된 인증 정보를 가져오기 위한 두 가지 방법이 있다.


1. EL태그로 Set해서 변수로 이용하기

<c:set var="login" value="${empty pageContext.request.userPrincipal.name }"/>


2. 일일이 pageContext객체에 접근하기

 ${pageContext.request.userPrincipal.name }


is empty여부를 판단해 로그인 상태인지, 아닌지를 판단할 수 있다.