Simple Authentication Servlet Filter with JSP/Servlet
자바에서 Servlet filters는 authetication, compression, auding, logging, image conversion, 웹 컨텐츠의 국제화등을 중앙에서 관리할 수 있도록 구현해 주는 인터페이스이다. 여기서 보여주는 서블릿 필터의 예제는 어떻게 간단하게 Java 기반의 웹 애플리케이션에서 인증을 수행하는가에 대해서 보여준다. 이것은 고객이 로그인을 수행했는지 여부와, 페이지가 익스파이어 되었는지, 그리고 각 페이지에 대한 퍼미션 정보를 이 컨텐츠를 통해서 다른 웹 페이지에서 수행하지 않도록 해 준다.
디자인 시나리오는 간단하다. HTTP request가 들어왔을때 로그인 하지 않은 사용자는 login page로 보내진다. 반면 인증된 사용자는 요청된 페이지로 이동을 수행하도록 한다. 사용자가 로그인할 때, 서블릿은 /auth를 호출하고, 인증을 관리한다. 그리고 로그인 실패시 다시 로그인 페이지로 이동하게 만든다. 또한 성공한 경우에는 요청한 페이지로 진행할 수 있도록 해 준다.
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
System.out.print("Authentication: Request received ...");
try {
boolean authorized = false;
if (request instanceof HttpServletRequest) {
HttpSession session = ((HttpServletRequest)request).getSession(false);
if (session != null) {
UserToken token = (UserToken) session.getAttribute("userToken");
String qryStr = ((HttpServletRequest)request).getQueryString();
if((token != null) || "cLogin".equalsIgnoreCase(qryStr))
authorized = true;
}
}
if (authorized) {
chain.doFilter(request, response);
} else if (filterConfig != null) {
ServletContext context = filterConfig.getServletContext();
String login_page = context.getInitParameter("login_page");
System.out.print("Authentication: Login page = " + login_page);
if (login_page != null && !"".equals(login_page)) {
context.getRequestDispatcher(login_page).forward(request, response);
}
} else {
throw new ServletException ("Unauthorized access, unable to forward to login page");
}
} catch (IOException io) {
System.out.println("IOException raised in AuthenticationFilter");
} catch (ServletException se) {
System.out.println("ServletException raised in AuthenticationFilter");
}
System.out.print("Authentication: Response dispatched ...");
}
- user token은 세션에 들어가있고, 이것은 서블릿에서 인증이 성공된 이후에 값이 세팅되게 된다. 이것은 사용자가 로그아웃 하거나 세션이 expire된 경우에는 자동으로 제거된다.
- 로그인 페이지는 인증용 쿼리의 인증을 위해서 인증 페이지를 호출한다. 이 예제에서는 login.jsp의 폼은 아마도 "http://domain/servlet/auth?cLogin"이 될 것이다. 아래를 보면 알 수 있다.
- 우리는 첫번째로 토큰을 검사하고, 이것이 적법한경우 우리는 쿼리 스트링을 확인하지 않는다. 이것은 반복적인 콜을 하지 않도록 해주는 중요한 기능이다.
- 인증이 성공하면 세션에서 사용자의 토큰이 존재하는지 검사하게 된다. 그러나 사용자가 로그인하는 경우에는 리퀘스트를 처리하도록 놓아둔다.
- 만약 인증이 실패하고, 올바른 설정값이 존재한다면 우리는 단순하게 로그인 페이지로 요청을 보내게 된다. 그렇지 않은경우 예외를 던진다. (아마도 절대로 이 상황은 오지 않을것이지만... ^^). 애플리케이션을 위한 기본적인 에러 페이지가 화면에 보일 것이다.
Add to the root <app> node.
<context-param>
<param-name>loginPage</param-name>
<param-value>/login.jsp</param-value>
</context-param>
<filter>
<filter-name>AuthFilter</filter-name>
<filter-class>com.package.AuthFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Code snippet for Login Page
<%
String urlParams = url + "/auth?cLogin";
%>
<form action="<%=urlParams%>" method="POST">
// Form components
</form>
Code snippet for Servlet:
- 보는것과 같이 doPost()메소드가 호출되면 이미 요청으로 부터 파라미터를 추출하게 된다. 파라미터가 cLogin이될 것이다.
private void performLogin(HttpServletRequest request, HttpServletResponse response, String username,
String password, ServletContext context) throws ServletException, IOException {
if((username!=null) & (password!=null)) {
User user = userFacade.findByUsername(username);
if(user!=null) {
UserToken tok = Authentication.authenticateUser(user, username, password);
if (tok != null) {
request.getSession().setAttribute("userToken", tok);
response.sendRedirect(context.getContextPath());
}
} else {
String url = context.getInitParameter("login_page");
if (url != null && !"".equals(url)) {
response.sendRedirect(url);
}
}
} else {
String url = context.getInitParameter("login_page");
if (url != null && !"".equals(url)) {
response.sendRedirect(url);
}
}
}
이게 다다. 웹 애플리케이션에 이 필터를 디플로이 하면 모든 요청에 대해서 인터셉터를 수행하고, 인증 검사를 수행하게 된다.
'Development > JSP & Servlet' 카테고리의 다른 글
JSP - 세션 관리 (0) | 2012.07.07 |
---|---|
JSP - session default timeout 설정 (0) | 2012.05.30 |
jsp/servlet scope (0) | 2012.05.14 |
JSP 소스 사이트 (0) | 2012.05.07 |
JSTL (JSP Standard Tag Library) (0) | 2012.03.28 |