質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.62%

JavaEE JAX-RS で実装したAPI でJDBCレルムの認証結果を取得

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,524

ShintaroIshida

score 79

以下のサイトの情報を元にglassfish のJDBCレルムを使ったユーザー認証方法の実装を試行錯誤しています。
http://www.slideshare.net/OracleMiddleJP/java-ee-detail-of-jdbcrealm?ref=http://yoshio3.com/2013/12/10/glassfish-jdbc-realm-detail/

上記資料の内容は、JavaEE・JSFで実装したWEBアプリケーションのJDBCレルム認証を使った方法で、
実際に手順通り行って、想定通りの結果(ユーザーの入力・削除、ログイン制御)を得られました。

これをJAX-RS Jersey で実装されたRestfulAPIで認証結果を得たいと考えています。

サービスの作成には以下の手順で行いました。
https://netbeans.org/kb/docs/websvc/rest_ja.html

ここで、自動生成されたサービスのファサードに以下の処理を記述し、
request.login の結果問題なければ、認証OK。Exception に落ちれば認証失敗としたいと考えています。

JSF版のログイン処理を参考にしてJAX-RSのファサードに判定処理を書いているのですが、
HttpServletRequestの周辺で、NullException が走ります。
import も通っていますし、IDEでのソース上では、一切エラー等出ていないのに関わらずです。

一応、認証チェック用のファサード処理を下記に記載します。

   / / Login Test
    @GET
    @Path("login/{username}/{password}")
    @Produces({"application/xml", "application/json"})
    public String login(@PathParam("username") String username, @PathParam("password") String password) {
        FacesContext context = FacesContext.getCurrentInstance();
        ExternalContext externalContext = context.getExternalContext();
        HttpServletRequest request = (HttpServletRequest)
                                            externalContext.getRequest();

        try{
            request.login(username, password);
        } catch(ServletException ex) {
            Logger.getLogger(UsertableFacadeREST.class.getName()).log(Level.INFO, null, ex);
            Logger.getLogger(UsertableFacadeREST.class.getName()).log(Level.INFO, "LoginFalse :: {0} :: {1}", new Object[]{username, password});
        }

        return username + " :: " + password;
    }
    
動かないという事は、間違っているという認識なのですが
同じ言語、同じ環境(JavaEE・glassfish)で動かないのかがわかりません。
動かす方法やヒントも知りたいです。

そもそも、javaへの理解が足りていない事は重々承知の上で、
お知恵を貸して頂けますと幸いです。

※エラー情報の追加 2015/8/7
HTTPエラー画面
exception
javax.servlet.ServletException: javax.ejb.EJBException

root cause
javax.ejb.EJBException

root cause
java.lang.NullPointerException

glassfishログ
警告:   EJB5184:A system exception occurred during an invocation on EJB UsertableFacadeREST, method: public java.lang.String entities.service.UsertableFacadeREST.login(java.lang.String,java.lang.String)
警告:   javax.ejb.EJBException
~省略~
Caused by: java.lang.NullPointerException
    at entities.service.UsertableFacadeREST.login(UsertableFacadeREST.java:93)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
~省略~
警告:   StandardWrapperValve[entities.service.ApplicationConfig]: Servlet.service() for servlet entities.service.ApplicationConfig threw exception
java.lang.NullPointerException
    at entities.service.UsertableFacadeREST.login(UsertableFacadeREST.java:93)
~省略~
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • eripong

    2015/08/06 18:16

    NullPointerExceptionのスタックトレースと、request.loginのコードを追加してもらえませんか?

    キャンセル

  • ShintaroIshida

    2015/08/07 09:44

    eripong 様

    追加させて頂きました。関連ありそうな部分を列挙してみたのですが。。。
    デバッグしてみると、
    ExternalContext externalContext = context.getExternalContext();

    ここの処理に入った後に落ちているようです。たぶん、JSF用の処理の仕方なので
    JAX-RSで利用できる形に変えればいいと思うのですが、その方法がわかりません。

    キャンセル

  • eripong

    2015/08/07 09:45 編集

    追加ありがとうございます。
    contextがnullなのですね。

    キャンセル

  • ShintaroIshida

    2015/08/07 09:49 編集

    eripong 様
    >UsertableFacadeREST.javaの93行目は、request.login(username, password);ですか?

    **ExternalContext externalContext = context.getExternalContext();**
    ここのようです。

    そもそもrequestを準備している一連の流れが何をしている処理なのか理解していないのが
    致命的だと思っています。ダメダメですね。

    キャンセル

回答 2

checkベストアンサー

+1

まず、FacesContextはJSF固有のものですので、JAX-RSと直接関係ありません。
そのため、JAX-RSのメソッド内では事前の初期化がされず、
nullになってしまっていたのだと思います。
「同じ言語、同じ環境(JavaEE・glassfish)」ではあっても、
JSFとJAX-RSでは動作は異なる、ということですね。

それから、フィールドとして@Contextした場合には、
おそらくこのクラスのインスタンス生成が、
リクエストのタイミングではなく、もっと前だったのではないかと思います。
リクエストされていない時にHttpServletRequestを設定しようとしても、
存在しないのでnullになっていたのだと思います。

以下の様に、メソッド引数に追加したらどうでしょうか?

public String login(@PathParam("username") String username, @PathParam("password") String password, @Context HttpServletRequest request) 

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/08/07 10:11

    通りました!!ありがとうございますmm

    動作も想定通りで、username・password が存在しない場合は、exceptionがキャッチしてくれています!

    ありがとうございましたmm

    お手数でなければ、どういう勘違いをしていたのか解説頂けないでしょうか?
    ここ見ればわかるという、URLの提示でもいいです。

    キャンセル

  • 2015/08/07 10:49

    説明を追記しました。これで伝わるでしょうか?

    キャンセル

  • 2015/08/07 10:58

    今回、
    結果的には大丈夫でしたが、Jerseyのバージョンなど、
    使用しているソフトウェア、ライブラリのバージョンは明記していただいた方が
    回答を付けやすいです。

    キャンセル

  • 2015/08/07 11:09

    ありがとうございますmm

    詳細な説明もありがとうございます。理解が深まりました。

    バージョンやライブラリの件、気を付けます。
    ありがとうございます。

    キャンセル

0

NullPointerException はコンパイル時には検出できませんので、IDE上はエラーになりませんよ。

データがあって初めてわかるものです。

スタックトレースを見てみないと分からないのですが、該当のソースの箇所が本当にエラーなら request オブジェクトがnullなのでしょう。

なので、Null.login() を実行しようとするから、Exceptionになっているのだと思います。

request オブジェクトは引数にありませんので、DIですか?
だとしたら、アノテーションを忘れてはいませんか?


投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/08/07 09:41

    NARH 様

    ソースに漏れがあったので、追加しました。
    HttpServletRequest にlogin 処理が既にある認識だったので。

    他に試した事としては、クラス直下に
    @Context
    private HttpServletRequest request;

    で準備して、呼んでみたのですがダメでした。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る