ジャージーでセッション管理またはセキュリティをプログラムで取得する方法はありますか (Web アプリケーション セッション管理など)。それとも、トランザクション、セッション、およびセキュリティはすべて、Jersey アプリケーションがデプロイされているコンテナーによって処理されますか?
7 に答える
セッション管理は、Jersey がデプロイされるコンテナーの範囲です。ほとんどの本番環境では、セッション管理を実行するコンテナー内にデプロイされます。
以下のコードは、セッション オブジェクトを取得して値をセッションに保存し、後続の呼び出しでそれらを取得する jersey リソースの簡単な例です。
@Path("/helloworld")
public class HelloWorld {
@GET
@Produces("text/plain")
public String hello(@Context HttpServletRequest req) {
HttpSession session= req.getSession(true);
Object foo = session.getAttribute("foo");
if (foo!=null) {
System.out.println(foo.toString());
} else {
foo = "bar";
session.setAttribute("foo", "bar");
}
return foo.toString();
}
}
セッションは、RESTful アプリケーションでは決して使用してはならないものだと思いました...
イェゴールは正しい。従来の Web アプリケーションのようにサーバー側で状態を維持するべきではありません。分離された SOA 指向のアプリケーションを構築する場合、REST Web サービス用の API/フレームワークを使用する必要はありません。サーバー側でグローバルなクライアント/サーバー状態を維持する必要がある、または維持したい場合は、SOA 指向の [Web] アプリとして説明できるものを暗黙的に構築していますが、一種の [Web] 開発フレームワークのように Jersey を使用しています。うっかりして、Web サービス (REST またはその他) の性質をねじ曲げています。最初の回答で提案されている方法でそれを行うことができますが、そうしてはなりません。最終的な結果は Web サービスではなく、Web サービスのツールで構築された通常のアプリです。
-_o
セッションに関するジャックの反応は正しいです。サーブレット仕様は少なくとも JavaEE コンテナー間の移植性を提供しますが、それらは実行するコンテナーに固有のものです。
セキュリティに関しては、少なくとも、JaaS (Java Authentication and Authorization Service) とサーブレット フィルターを使用して、JAX-RS 固有のコードからセキュリティを分離する機会があります。フィルターを使用して HTTP 認証を強制し、認証が成功すると、適切なプリンシパルを使用して JaaS サブジェクトをセットアップできます。JAX-RS リソースは、サブジェクトの適切なプリンシパルをチェックできます。スタック全体を制御するため、リソース内の認証済みユーザーに依存できるはずです (ただし、これをテストしてください!)。また、リソース コード内の現在の操作に基づいて承認を適用できます。
クライアントに Authorization ヘッダーを追加させ、REST メソッドで次のようにテストすることで、この問題を解決しました。
@GET
@PRODUCES(MediaType.APPLICATION_JSON)
public String returnClients(@Context HTTPServletRequest request(
String auth = request.getHeader("Authorization");
Account acc = null;
if (auth!=null) {
Account acc = Utils.LoginAccount(auth);
}
if (acc == null)
// not logged in, handle it gracefully
このようにして、セッションを開始せずに認証が行われます。
ジャージーのセキュリティについては、ジャージーのOAuthサポートを確認する必要があります。システムのAPIを外部ユーザーに公開する場合、OAuthは完全に適合します。たとえば、LinkedInAPIのように
@path を使用して、単一の名前空間でサービスをグループ化できます。例 。
@Path("/helloworld")
public class HelloWorld {
@GET
@Produces("text/plain")
public String hello() {
return "";
}
}
Instead of @Path("/helloworld") use
@Path("admin/helloworld") to expose you class as rest and bind filter on "admin/"
in web.xml as below.
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>/</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>myfilter</filter-name>
<filter-class>com.Filterclass</filter-class>
</filter>
<filter-mapping>
<filter-name>myfilter</filter-name>
<url-pattern>/rest/admin/*</url-pattern>
</filter-mapping>
public class Filterclass implements Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
try{
chain.doFilter(request, response);
}catch(Exception e){
e.printStackTrace();
}
}
}
このフィルター クラスでセッションを検証できます。