security-constraintによる認証と認可について
web.xml で security-constraint を記述すると、指定したURLパターンについてOpenID Providerによる認証が有効になります。認可の設定は role-name で指定します。
role-name=*
すべてのユーザに対してアクセスを許可します。
アプリケーションでは User#getFederatedIdentity() の値をチェックし、必要に応じてアクセス制御を行います。
<security-constraint> <web-resource-collection> <web-resource-name>Admin Utilities</web-resource-name> <url-pattern>/admin/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>*</role-name> </auth-constraint> </security-constraint>
role-name=admin
アプリケーションの所有者(自分のGoogleアカウント)に対してのみアクセスを許可します。それ以外のユーザには 403 Forbidden が返ります。
自分しか使わないツールのURLには admin を指定しておくとよいでしょう。
<security-constraint> <web-resource-collection> <web-resource-name>Admin Utilities</web-resource-name> <url-pattern>/admin/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> </auth-constraint> </security-constraint>
指定したユーザにアクセスを許可する方法
security-constraintによる認可では上記の2種類しか指定できないため、柔軟性に欠けます。
そこで、指定したユーザのみにアクセスを許可するサーブレットフィルタを書いてみました。
<filter> <filter-name>LoginFilter</filter-name> <filter-class>org.hidetake.app.healthcheck2.util.LoginFilter</filter-class> <init-param> <param-name>allowUserId</param-name> <param-value>http://www.hatena.ne.jp/int128/</param-value> </init-param> </filter> <filter-mapping> <filter-name>LoginFilter</filter-name> <url-pattern>/util/*</url-pattern> </filter-mapping>public class LoginFilter implements Filter { private final UserService userService = UserServiceFactory.getUserService(); private String allowUserId; public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { if(AppEngineUtil.isProduction()) { User user = userService.getCurrentUser(); if(user != null) { if(allowUserId.equals(user.getFederatedIdentity())) { chain.doFilter(request, response); } else { response.setStatus(403); response.setContentType("text/plain"); response.getWriter().append("403 Forbidden"); } } else { response.sendRedirect(userService.createLoginURL(request.getRequestURI(), request.getServerName(), allowUserId, Collections.<String>emptySet())); } } else { chain.doFilter(request, response); } } }https://github.com/int128/healthcheck2/blob/3ac977bb4f9979f3bdf4802d61138d970d50443a/src/org/hidetake/app/healthcheck2/util/LoginFilter.java