[쉽게 배우는 JSP 웹 프로그래밍] 10장 정리, 연습문제
웹 애플리케이션의 보안을 위해 선언적 시큐리티와 프로그래밍적 시큐리티 처리 방식을 사용할 수 있다. 선언적 시큐리티는 web.xml 파일에 보안 구성을 작성하여 수행하며, 프로그래밍적 시큐리티는 코드를 작성하여 사용자의 권한 부여를 처리한다. FORM 기반 인증 처리는 사용자가 로그인 페이지에 인증 정보를 직접 입력해야 하며, 로그인 페이지에서 form 태그의 action 속성 값은 j_security_check로, 사용자의 name 속성은 j_username으로, 비밀번호의 name 속성은 j_password로 설정해야 한다.
Feb 27, 2024
Contents
웹 서버에 역할과 사용자 구성하기tomcat-users.xml핵심 키워드선언적 시큐리티 처리tomcat-users.xmlweb.xmlsecurity01.jsplogin.jsplogin_failed.jsp핵심 키워드프로그래밍적 시큐리티 처리web.xmlsecurity02.jsp핵심 키워드연습 문제practice01.jsppractice04.jsppractice04_login.jsppractice04_login_failed.jsppractice05tomcat-users.xmlweb.xmllogin.jsplogin_failed.jsplogout.jspaddBook.jsp결론웹 서버에 역할과 사용자 구성하기
tomcat-users.xml
<?xml version="1.0" encoding="UTF-8"?> ... </tomcat-users> ... <!-- <role rolename="tomcat"/> <role rolename="role1"/> <user username="tomcat" password="tomcat1234" roles="tomcat"/> <user username="both" password="both1234" roles="tomcat,role1"/> <user username="role1" password="role1234" roles="role1"/> --> </tomcat-users>
핵심 키워드
- 웹 애플리케이션의 인증과 권한 부여를 위해 톰캣 서버에 사용자와 역할을 쉽게 생성하고 구성할 수 있다.
- tomcat-users.xml 파일에 주석 부분을 해제하면 기존에 설정된 역할과 사용자를 사용하거나 새로운 역할과 사용자를 추가할 수 있다.
선언적 시큐리티 처리
tomcat-users.xml
<!-- => 주석 처리 삭제 <role rolename="tomcat"/> <role rolename="role1"/> <user username="tomcat" password="tomcat1234" roles="tomcat"/> <user username="both" password="both1234" roles="tomcat,role1"/> <user username="role1" password="role1234" roles="role1"/> --> => 주석 처리 삭제
web.xml
<!-- <?xml version="1.0" encoding="UTF-8"?> <web-app> <security-role> <role-name>role1</role-name> </security-role> <security-constraint> <web-resource-collection> <web-resource-name>JSPBook</web-resource-name> <url-pattern>/ch10/security01.jsp</url-pattern> <http-method>GET</http-method> </web-resource-collection> <auth-constraint> <description></description> <role-name>role1</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> </login-config> </web-app> --> <?xml version="1.0" encoding="UTF-8"?> <web-app> <security-role> <role-name>role1</role-name> </security-role> <security-constraint> <web-resource-collection> <web-resource-name>JSPBook</web-resource-name> <url-pattern>/ch10/security01.jsp</url-pattern> <http-method>GET</http-method> </web-resource-collection> <auth-constraint> <description></description> <role-name>role1</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>FORM</auth-method> <form-login-config> <form-login-page>/ch10/login.jsp</form-login-page> <form-error-page>/ch10/login_failed.jsp</form-error-page> </form-login-config> </login-config> </web-app>
security01.jsp
<%@ page contentType="text/html; charset=utf-8"%> <html> <head> <title>Security</title> </head> <body> <p>인증 성공했습니다. </body> </html>
login.jsp
<%@ page contentType="text/html; charset=utf-8"%> <html> <head> <title>Security</title> </head> <body> <form name="loginForm" action="j_security_check" method="post"> <p> 사용자명: <input type="text" name="j_username"> <p> 비밀번호: <input type="password" name="j_password"> <p> <input type="submit" value="전송"> </form> </body> </html>
login_failed.jsp
<%@ page contentType="text/html; charset=utf-8"%> <html> <head> <title>Security</title> </head> <body> <p>인증 실패했습니다. </body> </html>
핵심 키워드
- 선언적 시큐리티는 웹 애플리케이션 배포 설명자 web.xml 파일에 보안 구성을 작성하여 수행하는 방식이다. 즉 웹 애플리케이션의 보안을 달성하기 위해 별도의 코드를 작성할 필요 없이 web.xml 파일에 보안 구성을 작성하여 웹 페이지에 접근할 수 있게 한다.
- <security-role>은 웹 애플리케이션에 사용하는 역할을 나열하는 요소다.
- <security-constraint>는 사용자의 요청 URL에 대한 접근 권한을 정의한다.
- <web-resource-collection>은 웹 자원에 대한 접근을 설정한다.
- <auth-constraint>는 웹 자원에 접근할 수 있는 인증된 사용자를 설정한다.
- <user-data-constraint>는 데이터 전송 시 데이터 보호를 설정한다.
- <web-resource-collection>은 웹 자원에 대한 접근을 설정하는 요소다.
- <web-resource-name>은 웹 자원의 이름을 설정하며 생략할 수 있다.
- <url-pattern>은 접근 제한을 요청할 URL 목록을 설정한다. 자원에 대한 접근을 제한하지 않는 경우 생략할 수 있다.
- <http-method> 또는 <http-method-omission>은 http 메소드를 설정한다(GET 또는 POST).
- <auth-constraint>는 권한이 부여된 사용자만이 웹 자원에 접근할 수 있도록 이름을 설정하는 요소다.
- <description>은 권한 부여 제약 사항에 대한 설명을 기술한다.
- <role-name>은 권한이 부여된 사용자의 이름을 대문자와 소문자를 구분하여 설정한다. 이 때 반드시 tomcat-users.xml에 등록된 역할과 사용자여야 한다. 만약 모든 사용자에게 권한을 부여하려면 *로 표시한다. <role-name>요소를 생략하면 <url-pattern>요소에 설정된 접근 제한 URL에 대한 사용자의 요청을 허용하지 않는다.
- <user-data-constraint>요소는 클라이언트와 서버 간에 데이터를 전송할 때 데이터를 보호하는 방법을 설정하는 요소다.
- <login-config>는 <security-constraint> 요소에 설정된 접근 제한 자원에 사용자가 접근하는 경우 해당 자원의 접근을 위한 인증 처리 방법을 활성화한다.
- <auth-method>는 웹 애플리케이션의 인증 처리 기법을 설정하는 요소다.
- <auth-method>의 요소 중 FORM 기반 인증 처리는 웹 브라우저가 인증 처리에 직접적으로 관여하지 않기 때문에 사용자가 로그인 페이지에 인증 정보를 직접 입력해야 전달된다. 이때 로그인 페이지에서 form 태그의 action 속성 값은 j_security_check로, 사용자의 name 속성은 j_username으로, 비밀번호의 name 속성은 j_password로 설정해야 한다.
- <realm-name>은 기본 인증의 영역 이름을 설정하는 요소다.
- <form-login-config>는 인증 처리를 위한 로그인 및 오류 페이지를 설정하는 요소다.
시큐리티 역할 설정
시큐리티 제약 사항 설정
시큐리티 인증 설정
프로그래밍적 시큐리티 처리
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app> <security-role> <role-name>role1</role-name> </security-role> <security-constraint> <web-resource-collection> <web-resource-name>JSPBook</web-resource-name> <url-pattern>/ch10/security02.jsp</url-pattern> <http-method>GET</http-method> </web-resource-collection> <auth-constraint> <description></description> <role-name>role1</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>FORM</auth-method> <form-login-config> <form-login-page>/ch10/login.jsp</form-login-page> <form-error-page>/ch10/login_failed.jsp</form-error-page> </form-login-config> </login-config> </web-app>
security02.jsp
<%@ page contentType="text/html; charset=utf-8"%> <html> <head> <title>Security</title> </head> <body> <p> 사용자명 : <%=request.getRemoteUser() %> <p> 인증방법 : <%=request.getAuthType() %> <p> 인증한 사용자명이 역할명 "tomcat"에 속하는 사용자인가요? <%=request.isUserInRole("tomcat") %> <p> 인증한 사용자명이 역할명 "role1"에 속하는 사용자인가요? <%=request.isUserInRole("role1") %> </body> </html>
핵심 키워드
- 프로그래밍적 시큐리티는 웹 애플리케이션의 보안을 위해 코드를 작성하여 사용자의 권한 부여를 처리하는 방식이다. 선언적 시큐리티의보안으로 충분하지 않을 때 request 내장 개체의 메소드를 사용하여 사용자를 승인하는 방법이다.
연습 문제
practice01.jsp
01 시큐리티는 허가된 사용자만이 특정 웹 페이지에 접근할 수 있도록 제한하는 보안 기능이다. 02 선언적 시큐리티는 웹 애플리케이션 배포 설명자 web.xml파일에 보안 구성을 작성하여 수행하는 방식이다. 프로그래밍적 시큐리티는 웹 어플리케이션의 보안을 위해 코드를 작성하여 사용자의 권한 부여를 처리하는 방식이다. 03 FORM 기반 인증 처리는 웹 브라우저가 인증 처리에 직접적으로 관여하지 않기 때문에 사용자가 로그인 페이지에 인증 정보를 직접 입력해야 전달된다. 이때 로그인 페이지에서 form 태그의 action 속성 값은 j_security_check로, 사용자의 name 속성은 j_username으로, 비밀번호의 name 속성은 j_password로 설정해야 한다.
practice04.jsp
<%@ page contentType="text/html; charset=utf-8"%> <html> <head> <title>Security</title> </head> <body> <p> 사용자명 <%=request.getRemoteUser() %> 인증을 성공했습니다. </body> </html>
practice04_login.jsp
<%@ page contentType="text/html; charset=utf-8"%> <html> <head> <title>Security</title> </head> <body> <form name="loginForm" action="j_security_check" method="post"> <p> 사용자명: <input type="text" name="j_username"> <p> 비밀번호: <input type="password" name="j_password"> <p> <input type="submit" value="전송"> </form> </body> </html>
practice04_login_failed.jsp
<%@ page contentType="text/html; charset=utf-8"%> <html> <head> <title>Security</title> </head> <body> <p>인증을 실패했습니다. </body> </html>
practice05
tomcat-users.xml
<!-- => 주석 처리 삭제 <role rolename="tomcat"/> <role rolename="role1"/> <role rolename="admin"/> <role rolename="guest"/> <user username="tomcat" password="tomcat1234" roles="tomcat"/> <user username="both" password="both1234" roles="tomcat,role1"/> <user username="role1" password="role1234" roles="role1"/> <user username="admin" password="admin1234" roles="admin"/> <user username="guest" password="guest1234" roles="guest"/> --> => 주석 처리 삭제
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app> <security-role> <role-name>guest</role-name> </security-role> <security-constraint> <display-name>WebMarket Security</display-name> <web-resource-collection> <web-resource-name>WebMarket</web-resource-name> <description></description> <url-pattern>/addBook.jsp</url-pattern> </web-resource-collection> <auth-constraint> <description>권한 관리자명</description> <role-name>guest</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>FORM</auth-method> <form-login-config> <form-login-page>/login.jsp</form-login-page> <form-error-page>/login_failed.jsp</form-error-page> </form-login-config> </login-config> </web-app>
login.jsp
<%@ page contentType="text/html; charset=utf-8"%> <html> <head> <link rel="stylesheet" href="./resources/css/bootstrap.min.css"> <title>Login</title> </head> <body> <jsp:include page="menu.jsp" /> <div class="jumbotron"> <div class="continer"> <h1 class="display-3">로그인</h1> </div> </div> <div class="container" align="center"> <div class="col-md-4 col-md-offset-4"> <h3 class="form-signin-heading">Please sign in</h3> <% String error = request.getParameter("error"); if (error != null) { out.println("<div class='alert alert-danger'>"); out.println("아이디와 비밀번호를 확인해주세요"); out.println("</div>"); } %> <form class="form-signin" action="j_security_check" method="post"> <div class="form-group"> <label for="inputUserName" class="sr-only">User Name</label> <input type="text" class="form-control" placeholder="ID" name='j_username' required autofocus> </div> <div class="form-group"> <label for="inputPassword" class="sr-only">Password</label> <input type="password" class="form-control" placeholder="Password" name='j_password' required> </div> <button class="btn btn btn-lg btn-success btn-block" type="submit">로그인</button> </form> </div> </div> </body> </html>
login_failed.jsp
<% response.sendRedirect("login.jsp?error=1"); %>
logout.jsp
<%@ page contentType="text/html; charset=utf-8"%> <% session.invalidate(); response.sendRedirect("addBook.jsp"); %>
addBook.jsp
<%@ page contentType="text/html; charset=utf-8"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> <html> <head> <link rel="stylesheet" href="./resources/css/bootstrap.min.css" /> <script type="text/javascript" src="./resources/js/validation.js"></script> <title>도서 등록</title> </head> <body> <fmt:setLocale value='<%=request.getParameter("language")%>' /> <fmt:bundle basename="bundle.message"> <jsp:include page="menu.jsp" /> <div class="jumbotron"> <div class="container"> <h1 class="display-3"> <fmt:message key="title" /> </h1> </div> </div> <div class="container"> <div class="text-right"> <a href="?language=ko">Korean</a>|<a href="?language=en">English</a> <a href="logout.jsp" class="btn btn-sm btn-success pull-right">logout</a> </div> <form name="newProduct" action="./processAddBook.jsp" class="form-horizontal" method="post" enctype="multipart/form-data"> <div class="form-group row"> <label class="col-sm-2"><fmt:message key="bookId" /></label> <div class="col-sm-3"> <input type="text" id="bookId" name="bookId" class="form-control"> </div> </div> <div class="form-group row"> <label class="col-sm-2"><fmt:message key="name" /></label> <div class="col-sm-3"> <input type="text" id="name" name="name" class="form-control"> </div> </div> <div class="form-group row"> <label class="col-sm-2"><fmt:message key="unitPrice" /></label> <div class="col-sm-3"> <input type="text" id="unitPrice" name="unitPrice" class="form-control"> </div> </div> <div class="form-group row"> <label class="col-sm-2"><fmt:message key="author" /></label> <div class="col-sm-3"> <input type="text" name="author" class="form-control"> </div> </div> <div class="form-group row"> <label class="col-sm-2"><fmt:message key="publisher" /></label> <div class="col-sm-3"> <input type="text" name="publisher" class="form-control"> </div> </div> <div class="form-group row"> <label class="col-sm-2"><fmt:message key="releaseDate" /></label> <div class="col-sm-3"> <input type="text" name="releaseDate" class="form-control"> </div> </div> <div class="form-group row"> <label class="col-sm-2"><fmt:message key="totalPages" /></label> <div class="col-sm-3"> <input type="text" name="totalPages" class="form-control"> </div> </div> <div class="form-group row"> <label class="col-sm-2"><fmt:message key="description" /></label> <div class="col-sm-5"> <textarea name="description" cols="50" rows="2" class="form-control"></textarea> </div> </div> <div class="form-group row"> <label class="col-sm-2"><fmt:message key="category" /></label> <div class="col-sm-3"> <input type="text" name="category" class="form-control"> </div> </div> <div class="form-group row"> <label class="col-sm-2"><fmt:message key="unitsInStock" /></label> <div class="col-sm-3"> <input type="text" id="unitsInStock" name="unitsInStock" class="form-control"> </div> </div> <div class="form-group row"> <label class="col-sm-2"><fmt:message key="condition" /></label> <div class="col-sm-5"> <input type="radio" name="condition" value="New "> <fmt:message key="condition_New" /> <input type="radio" name="condition" value="Old "> <fmt:message key="condition_Old" /> <input type="radio" name="condition" value="Refurbished "> <fmt:message key="condition_Refurbished" /> </div> </div> <div class="form-group row"> <label class="col-sm-2"><fmt:message key="bookImage" /></label> <div class="col-sm5"> <input type="file" name="bookImage" class="form-control"> </div> </div> <div class="form-group row"> <div class="col-sm-offset-2 col-sm-10"> <input type="submit" class="btn btn-primary" value="<fmt:message key="button" />" onclick="CheckAddBook()"> </div> </div> </form> </div> </fmt:bundle> </body> </html>
결론
해당 코드를 작성하면서 시큐리티의 개념, 선언적 시큐리티 처리 방법, 프로그래밍적 시큐리티 처리 방법을 익힐 수 있었다.
Share article