セキュリティ対応については認証用APIとセキュリティ制約の追加について紹介します。
Servlet 3.0からServlet APIに以下の認証用メソッドが追加されました。
上記メソッドを利用すると標準のServlet APIを利用して独自の認証プログラムを作成できます。
認証メソッドは「login(String username, String password)」「authenticate (HttpServletResponse response)」の2種類が用意されています。
authenticateメソッドではTomcatがデフォルトで提供している認証スキーム(BASIC、CLIENT-CERT、DIGEST、FORM、NONEなど)を利用して認証します。従って、
loginメソッドではTomcatが提供する認証スキームを利用せず、指定されたユーザーとパスワードで直接Realm認証を行います。Realm認証の前後にプログラミングにより自由に処理を追加できるため、独自の認証スキームも作成可能です。
loginメソッドとauthenticateメソッドのどちらを利用する場合でもRealmを切り替えることでユーザー名とパスワード、ロールを管理するデータベースを切り替えられます(参考:Apache Tomcat 7 Configuration Reference (7.0.14) - The Realm Component)。
logoutメソッドでは、ログアウト処理を行います。logoutメソッドを呼び出すことで認証情報をリクエストやセッションから削除します。
以下は、認証用APIの簡単なサンプルです。
@WebServlet(name = "LoginServlet", urlPatterns = { "/login" })
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String userName = req.getParameter("user");
String password = req.getParameter("password");
try {
if (req.getUserPrincipal() != null) {
resp.getWriter().print("already authenticated!");
}
req.login(userName, password);
} catch (ServletException exp) {
resp.getWriter().print("Login Failed!");
// TODO Handle Exception
}
}
}
サンプルではリクエストから取得したユーザー名とパスワードを利用して、ログイン認証を行います。
Servlet 3.0ではsecurity-constraintを追加する方法として3つの方法を提供しています。
今回はアノテーションによるセキュリティ制約の追加を紹介します。
Servlet 3.0から「@ServletSecurity」アノテーションが追加されました。@ServletSecurityではアノテートしたServlet・Filterに対してセキュリティ制約を追加でき、web.xmlの
また、@ServletSecurityの内部で利用するアノテーションとして「@HttpConstraint」「@HttpMethodConstraint」も追加されています。
@HttpConstraintでは、@HttpMethodConstraintが制約しない全てのHTTPメソッドに対して適用されるセキュリティ制約を表現するために利用されます。@HttpMethodConstraintは特定のHTTPメソッドのセキュリティ制約を表現するために利用されます。
今回も基本的な制約の例をサンプルとして掲載します。より詳しい使い方はServlet 3.0の仕様書を確認してください。
以下では、全てのHTTPメソッドに対して、アクセスを拒否しています。
@ServletSecurity(@HttpConstraint(EmptyRoleSemantic.DENY))
@WebServlet(name = "DenyServlet", urlPatterns = { "/deny" })
public class DenyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
}
}
以下では、全てのHTTPメソッドからのアクセスに対して、「Role="role1"」を要求します。
@ServletSecurity(value = @HttpConstraint(rolesAllowed = { "role1" }))
@WebServlet(name = "AllMethodRestrictServlet", urlPatterns = { "/all" })
public class AllMethodRestrictServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().print("Hello!");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().print("Hello!");
}
}
以下では、GETメソッドからのアクセスに対してはセキュリティ制約なし、それ以外のメソッドに対しては、「Role="role2"」を要求します。
@ServletSecurity(value = @HttpConstraint(rolesAllowed = { "role2" }),
httpMethodConstraints = @HttpMethodConstraint("GET"))
@WebServlet(name = "ExcludeGetMethodRestrictServlet", urlPatterns = { "/excget" })
public class ExcludeGetMethodRestrictServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().print("Hello!");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().print("Hello!");
}
}
GETメソッドからのアクセスに対しては「Role="role3"」を要求しています。それ以外のメソッドに対しては、セキュリティ制約はありません。
ServletSecurity(httpMethodConstraints = @HttpMethodConstraint(value = "GET", rolesAllowed = "role3")) @WebServlet(name = "GetMethodRestrictServlet", urlPatterns = { "/get" }) public class GetMethodRestrictServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().print("Hello!"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().print("Hello!"); } }
次ページで、残りの2つを説明します。
Copyright © ITmedia, Inc. All Rights Reserved.