最後にそれを機能させました!
Tomcat と Jersey で動作させる手順は次のとおりです。
TOMCAT_HOME/conf/tomcat-users.xml に次の内容があると仮定します。ここで、編集者とメンバーの 2 つのロールを定義します。
また、gavin、julie、および admin の 3 人のユーザーも定義します。
<?xml version="1.0" encoding="UTF-8"?>
<role rolename="editor"/>
<role rolename="member"/>
<user username="admin" password="qwerty" roles="editor,member"/>
<user username="gavin" password="qwerty" roles="editor"/>
<user username="julie" password="qwerty" roles="member"/>
</tomcat-users>
ステップ 1. web.xml で Servlet 3.0 仕様を使用していることを確認する
セキュリティ アノテーションは、Servlet 2.5 以下では機能しません。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
</web-app>
ステップ 2. アプリケーション クラスを作成してセキュリティ アノテーションを有効にする
注: 以下のコードは、Jersey に固有のものです。
package ph.activelearning.rest.security;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature;
public class MyApplication extends ResourceConfig {
public MyApplication() {
super(TestResource.class);
register(RolesAllowedDynamicFeature.class);
}
}
ステップ 3. web.xml でアプリケーション クラスを指定する
ステップ 2 で作成した Application クラスが Jersey によって認識されることを確認します。
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>ph.activelearning.rest.security</param-value>
</init-param>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>ph.activelearning.rest.security.MyApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
ステップ 4. web.xml で security-constraint を作成する
皮肉なことに、セキュリティ アノテーションを使用したい場合でも、web.xml でセキュリティ制約を定義する必要があります。
以下の例では、/test/* へのアクセスを保護しようとしています。HTTP メソッドを指定しないことが重要です。(ex. <http-method>GET</http-method>
) これは、すべての HTTP メソッドへのアクセスを拒否していることを意味します。
<auth-constraint>
それでも、要素を介して、メソッドに関係なく、URL にアクセスできるすべてのロールを定義する必要があります。
<web-app …>
<security-constraint>
<web-resource-collection>
<web-resource-name>test</web-resource-name>
<url-pattern>/test/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>editor</role-name>
<role-name>member</role-name>
</auth-constraint>
</security-constraint>
</web-app>
ステップ 5. web.xml で認証方法を指定する
次の例は、BASIC 認証を示しています。
<web-app …>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>test</realm-name>
</login-config>
</web-app>
ステップ 6. セキュリティ ロールを定義する
セキュリティ ロールは、tomcat-users.xml で定義された同じロールに対応する必要があります。この例では、役割の編集者とメンバーを定義します。
注:認証/承認がなくても機能するため、この手順はオプションのようです。
<web-app ...>
<security-role>
<description>This is editor</description>
<role-name>editor</role-name>
</security-role>
<security-role>
<description>This is member</description>
<role-name>member</role-name>
</security-role>
</web-app>
ステップ 7. リソースに注釈を付ける
package ph.activelearning.rest.security;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.SecurityContext;
@Path("test")
@PermitAll
public class TestResource {
@GET
@Path("editor")
@Produces(MediaType.TEXT_PLAIN)
@RolesAllowed("editor")
public String editorOnly() {
return "Got to editor path!";
}
@GET
@Path("member")
@Produces(MediaType.TEXT_PLAIN)
@RolesAllowed("member")
public String memberOnly() {
return "Got to member path!";
}
@GET
@Path("open")
@Produces(MediaType.TEXT_PLAIN)
public String open(@Context SecurityContext context) {
return "Open to all! - " + context.getUserPrincipal().getName();
}
}
それでおしまい。プログラミングを楽しむための完全な web.xml を次に示します。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>ph.activelearning.rest.security</param-value>
</init-param>
<!-- Define the Application class where we enable security annotations -->
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>ph.activelearning.rest.security.MyApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- Required even though we use annotations -->
<security-constraint>
<web-resource-collection>
<web-resource-name>test</web-resource-name>
<url-pattern>/test/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>editor</role-name>
<role-name>member</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>test</realm-name>
</login-config>
<!-- Optional: Define security roles that are defined in your app server -->
<!--
<security-role>
<description>This is editor</description>
<role-name>editor</role-name>
</security-role>
<security-role>
<description>This is member</description>
<role-name>member</role-name>
</security-role>
-->
</web-app>