Spring security 2.0 따라하기

From JCFWiKi

Jump to: navigation, search

그림:check.gif

  • 산출물 :Spring security 2.0 따라하기
  • 작성자: 나윤주
  • 최초작성일 : 2008/05/03
  • 최종작성일 : 2008/05/21

Copyright © 2008 Daewoo Information Systems Co., Ltd.

그림:information.gif

  • 이 가이드를 따라하시면 아래의 기능을 추가할 수 있습니다.
    • 유저 권한 체계 생성 및 유저에 권한 부여
    • 로그인 및 로그아웃
    • 특정 url에 권한 부여
    • 특정 메소드에 권한 부여

목차

[편집] 라이브러리 등록하기

  • 아래의 2개의 라이브러리를 /WEB-INF/lib/ 에 임포트한다.
    • spring-security-core-2.0.0.jar
    • spring-security-taglibs-2.0.0.jar
  • 라이브러리 다운받기: 다운로드
  • Spring security 2.0이 원활하게 동작하기 위해서는 spring framework 버전을 2.5 이상으로 한다.

[편집] web.xml 등록하기

  • web/WEB-INF/web.xml에서 DelegatingFilterProxy filter를 추가해줌 (Filter 설정 순서에 주의하세요.)
<filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter>
	<filter-name>struts-cleanup</filter-name>
		<filter-class>
			org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
</filter>
<filter>
	<filter-name>struts2</filter-name>
	<filter-class>
			org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
 
<filter-mapping>
      <filter-name>springSecurityFilterChain</filter-name>
      <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
	<filter-name>struts-cleanup</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
	<filter-name>struts2</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

[편집] Security 2.0 적용 table 생성하기

[편집] USERINFO table 만들기

CREATE TABLE userinfo (
	username VARCHAR(50) NOT NULL PRIMARY KEY,
	password VARCHAR(50) NOT NULL,
	ENABLED int DEFAULT '0'  NOT NULL
);

[편집] AUTHORITIES table 만들기

CREATE TABLE AUTHORITIES (
    USERNAME VARCHAR(12) NOT NULL,
    AUTHORITY VARCHAR(20) NOT NULL)

[편집] sample query 넣기

INSERT INTO userinfo VALUES ('marissa', 'koala', 0);
INSERT INTO userinfo VALUES ('dianne', 'emu', 1);
INSERT INTO authorities VALUES ('marissa', 'ROLE_ADMINISTRATOR');
INSERT INTO authorities VALUES ('dianne', 'ROLE_USER');
INSERT INTO authorities VALUES ('dianne', 'ROLE_GUEST');
  • USERINFO의 ENABLED 값이 1인 경우만 로그인이 가능하다.

[편집] 그외 blog 샘플 쿼리 넣기

CREATE TABLE IF NOT EXISTS `blog` (
  `id` int(11) NOT NULL DEFAULT '0',
  `title` varchar(50) DEFAULT NULL,
  `writer` varchar(50) DEFAULT NULL,
  `description` varchar(500) DEFAULT NULL,
  `regDate` date DEFAULT NULL,
  `isPublic` char(1) DEFAULT NULL,
  `categoryId` varchar(50) DEFAULT NULL,
  `attach` varchar(50) DEFAULT NULL,
  `attachBlob` blob,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 
CREATE TABLE IF NOT EXISTS `code` (
  `id` int(11) NOT NULL DEFAULT '0',
  `name` varchar(20) DEFAULT NULL,
  `description` varchar(50) DEFAULT NULL,
  `category` varchar(20) DEFAULT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 
 
INSERT INTO `code` (`id`, `name`, `description`, `category`) VALUES
(1, 'SEOUL', '서울', 'user_address_code'),
(2, 'INCHEN', '인천', 'user_address_code'),
(3, 'PUSAN', '부산', 'user_address_code'),
(4, 'ULSAN', '울산', 'user_address_code'),
(5, 'SEOUL', '서울', 'blog_category_code'),
(6, 'INCHEN', '인천', 'blog_category_code'),
(7, 'PUSAN', '부산', 'blog_category_code'),
(8, 'ULSAN', '울산', 'blog_category_code');

[편집] applicationContext-security.xml 설정하기

  • security 설정을 담당하는 applicationContext 파일을 생성한다.
    • src/config 밑에 applicationContext-security.xml 생성
  • applicationContext-security.xml 시작하기
<?xml version="1.0" encoding="UTF-8"?>
 
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sec="http://www.springframework.org/schema/security"
	xmlns:p="http://www.springframework.org/schema/p"
	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">
 
 
        	
</beans:beans>

[편집] 로그인 form 설정하기

  • <http> 설정으로 허용된 사용자만 접근이 가능하게 할 수 있다.
    • spring security 2.0에서는 로그인 폼을 제공하므로 별도의 로그인 폼을 작성하지 않아도 사용할 수 있다.
        <sec:http auto-config="true">
   		<intercept-url pattern="/**" access="ROLE_USER" />
        </sec:http>
  • <intercept-url>은 여러개를 정의할 수 있으며, 위에서부터 차례로 해당되는 url pattern이 적용된다.
  • 직접 작성한 로그인 폼을 쓰고자 한다면, <http> 설정을 다음과 같이 할 수 있다.
    • 직접 작성한 로그인 폼을 쓸 경우, 직접 작성한 로그인 폼은 누구나 접근할 수 있어야 하기 때문에 /** pattern의 사용에 주의한다.
<sec:http auto-config='true'>
		<sec:form-login login-page="/public/blog/login.jsp"
			authentication-failure-url="/public/blog/login.jsp" default-target-url="/blog/findBlogs.action"
			always-use-default-target='true' />
		<sec:logout logout-success-url="/public/blog/login.jsp" />
		<sec:intercept-url pattern="/"
			access="IS_AUTHENTICATED_ANONYMOUSLY" />
		<sec:intercept-url pattern="/public/blog/login.jsp" filters='none' />
		<sec:intercept-url pattern="/blog/**" access="ROLE_USER" />
	</sec:http>

[편집] JDBC를 이용한 사용자 인증

  • 사용자 정보를 xml에 등록하여 사용할 수도 있지만, 여기서는 데이터베이스에 저장된 사용자 정보를 이용하여 사용자 인증을 한다.
<sec:global-method-security secured-annotations="enabled">
		<!--
			AspectJ pointcut expression that locates our "post" method and
			applies security that way <protect-pointcut expression="execution(*
			bigbank.*Service.post*(..))" access="ROLE_TELLER"/>
		-->
	</sec:global-method-security>
 
<sec:authentication-provider>
		<sec:jdbc-user-service data-source-ref="dataSource"
			users-by-username-query="SELECT username,  password,  enabled   FROM USERS where username = ?"
			authorities-by-username-query="SELECT username, authority from authorities where username = ?"
			group-authorities-by-username-query="SELECT g.id, g.group_name,	ga.authority
FROM groups g, group_members gm, group_authorities ga
WHERE gm.username = ? AND g.id = ga.group_id AND g.id = gm.group_id" />
 
	</sec:authentication-provider>

[편집] 인증 view page 만들기

  • 사용자 인증에 사용할 로그인 폼은 직접 작성하여 사용 할 수 있다.
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
 
<html>
<head>
<title>JCF EDUCATION::BLOG</title>
</head>
 
<body>
	<div align="center">
		<h1>JCF EDUCATION - BLOG</h1>
		<hr width="600">
 
		<h2>블로그 로그인</h2>
		
		<form action="<s:url value='/j_spring_security_check'/>" method="POST">
			<table>
				<tr><td>User:</td><td><input type='text' name='j_username'></td></tr>
				<tr><td>Password:</td><td><input type='password' name='j_password'></td></tr>
				<tr><td colspan='2' align="center"><input name="submit" type="submit" value="로그인">
					         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                                                 <input name="reset" type="reset" value="취소"></td></tr>
			</table>
		</form>
		
	</div>
</body>
</html>

[편집] Spring seucrity 2.0 태그 사용하기

  • 앞서 추가한 spring-security-taglibs-2.0.0.jar를 참조한다.
  • findBlogs.jsp
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib uri="/WEB-INF/tld/app.tld" prefix="app" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
 

<!-- 중간생략 -->   <!-- 권한에 따라 페이지에서 보여주는 것을 달리하기 위해 authorize 태그를 사용할 수 있다. --> <sec:authorize ifNotGranted="ROLE_USER"> <a href="<s:url value="/public/blog/login.jsp"/>">로그인</a> </sec:authorize> <sec:authorize ifAnyGranted="ROLE_USER, ROLE_ADMIN"> <b><sec:authentication property="principal.username"/></b>님 반갑습니다. <br> <a href="<s:url value="/j_spring_security_logout"/>">로그아웃</a> </sec:authorize>  

<!-- 이하생략 -->
  • 수정 및 삭제 버튼도 위에서 사용한 authorize 태그를 사용해서 로그인 상태에 따라 보여주거나 보여주지 않을 수 있다.
  • authentication 태그를 사용하여 현재 로그인된 사용자의 정보를 확인할 수 있다.

[편집] Spring Security Tag Library

  • authentication 태그
    • property="principal.username" 설정으로 현재 로그인 된 사용자의 username을 확인 할 수 있다.
  • authorize 태그
    • 현재 로그인 된 사용자가 해당되는 권한에 따라, 태그 안에 포함된 내용을 보여주거나 보여주지 않을 수 있다.
    • ifAllGranted 속성: 사용자가 나열된 모든 권한에 해당할 경우 태그 안에 포함된 내용을 보여준다.
    • ifAnyGranted 속성: 사용자가 나열된 권한 중 한가지에라도 해당할 경우 태그 안에 포함된 내용을 보여준다.
    • ifNotGranted 속성: 사용자가 나열된 권한 중 한가지에라도 해당할 경우 태그 안에 포함된 내용을 보여주지 않는다.