2012-01-15 12 views
7

私は、さまざまなWebクライアント(ブラウザ、ネイティブモバイルアプリケーションなど)を使用するユーザーが登録できるようにするWebアプリケーションを用意しています。ログイン後、制限されたコンテンツや自分のコンテンツ(作成したエントリなど)にアクセスできます。私は次のメソッドを公開JAX-RS残りのWebサービスを(私はGlassFishの上で自分のアプリケーションをホスティングしています)作成:私はこれまでやったjax-rs webサービスの認証と承認を外します

  • レジスタ - ユーザーPOSTの彼の希望のユーザー名/パスワード/電子メール/ etc。ユーザー名/電子メールが一意の場合、このユーザーのエントリがデータベースに作成されます(私は永続性のためにHibernateを使用しています)
  • ログインユーザーのユーザー名とパスワード。それらが正常であれば、UUIDが作成され、ユーザーに返されます(これは将来の要求のトークンとして使用されます)。私はlogedusersと呼ばれるテーブルを持っています。userID、token、validSinceは列です。

ここで私は混乱するところです。

私は、ユーザーが行ったすべてのエントリを返すgetUserEntriesという別のメソッドがあるとしましょう。これを明確にするために、entryId、userId、textというフィールドを持つEntryテーブルがあります。

ここで最善のアプローチは何ですか?トークンが有効であれば、私はlogedusersテーブルとベースのユーザIDを取得し、その後

localhost:8080/myApp/getUserEntries?token=erf34c34

:私は今、私がGET要求を行うされており、このようにトークンを渡すかどう

そのuserId上で、すべてのエントリを取得し、それらをjsonとして返します。このような

何か:しかし

@GET 
@Path("getUserEntries") 
@Produces(MediaType.APPLICATION_JSON) 
public Response getUserEntries(@QueryParam("token") String token) {  
    String userId=getUserIdFromToken(token); 
    if (userId == null){ 
     return Response.status(Response.Status.UNAUTHORIZED).build(); 
    } else { 
     //get some data associated with that userId, put it in the response object and send it back 
     return Response.ok().entity(response).build(); 
    } 
} 

、私は彼らが有効なユーザーによって呼び出された場合にデータを提供する複数のメソッドを持っている場合、何が起こりますか?

私はすべての方法の冒頭でこのチェックを行う必要があります。私は

この認証プロセスを透明にしたい

だから、ここでは2つの主要な質問:

  1. は大丈夫、この設計ですか?全体がユーザー/パスで認証され、サーバーがトークンを作成して保存してユーザーに送信し、ユーザーは将来の要求でトークンを送信します。
  2. 発信ユーザの身元を判断する必要のあるエンドポイントが多数ある場合はどうすればよいですか?いくつかのアノテーションを付けてマークすることができます。セキュリティプロバイダ/オーセンティケータを使用できます(トークンが5日以上経過していないかどうかを確認するなど、独自のロジックを追加できます)。

おかげ

答えて

2

は、この設計は大丈夫ですか?全体がユーザー/パスで認証され、サーバーがトークンを作成して保存してユーザーに送信し、ユーザーは将来の要求でトークンを送信します。

多少問題はありません。概念レベルはそれほど悪くないが(自己登録であれば問題ありませんが)、インターフェイスには多くの調整が必要です。はい、POSTを登録してログインするのは正しいですが、残りのWebアプリケーションでは必要に応じてコンテキストからID情報を引き出し、可能な限りメソッドレベルでロールベースのアクセス制御を使用する必要があります。

コンテナには、一連の認証および認可サポートメカニズムが組み込まれていることに注意してください。

発信ユーザーの身元を判断する必要のあるエンドポイントが多数ある場合はどうすればよいですか?いくつかのアノテーションを付けてマークすることができます。セキュリティプロバイダ/オーセンティケータを使用できます(トークンが5日以上経過していないかどうかを確認するなど、独自のロジックを追加できます)。

となりますか?または、ユーザーがアクセスできることを知るだけでいいですか?後者の場合、最も簡単な方法は、適切な@RolesAllowed注釈をメソッドに配置することです(このとき、適切な構成で、JEE5 security docsを参照)。前者の場合は、現在のアクションのためにHttpServletRequestオブジェクトを取得し、そのユーザーの身元を取得するためのメソッド(getUserPrincipal())を呼び出す必要があります(まだログインしていない場合はnull)。 This SO questionはリクエストオブジェクトの取得方法について説明しています。それを行うにはいくつかの方法がありますが、私は@Resourceアノテーションを使って注入することをお勧めします。

私がしないことは、ユーザーが通常@QueryParamで自分の身元を提供できることです。それは荒々しく乱暴に開いているだけです。あなたはそれらを他のユーザーに聞いてもらうことができます。しかし、あなたは、現在のユーザーが他のユーザーについて何かを知ることが許可されているかどうかに基づいて、何かを伝えるかどうかを決定する必要があります。これは、実際のアプリに登場する複雑なセキュリティ問題の一種であり、現在の検証されたユーザIDを必要とする良い点です。