2015年2月18日水曜日

JSPのコンパイル時に非常に奇妙なエラーが出る

This static method of interface XXX can only be accessed as XXX
というような例外メッセージになる。

例えば、XXXインターフェースにyyyメソッドがあり、それをJSPでXXX.yyyと呼び出した場合。
その通りやってんだろうがよ!と怒りたくなる。つうか腹たつなもう。

解決策は、Tomcatのweb.xml、


<servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
        <init-param>
            <param-name>fork</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>xpoweredBy</param-name>
            <param-value>false</param-value>
        </init-param>
  <!-- こっから -->
  <init-param>
      <param-name>compilerSourceVM</param-name>
      <param-value>1.8</param-value>
  </init-param>
  <init-param>
      <param-name>compilerTargetVM</param-name>
      <param-value>1.8</param-value>
  </init-param>
  <!-- ここまで -->
        <load-on-startup>3</load-on-startup>
</servlet>


「こっからここまで」を足したら直った。けど、今までEclipse上のTomcatでは1.7の指定で(JREは1.8だった)大丈夫だったのが解せない。1.7の指定が効いていなかったワケではなく、ちゃんとラムダとかはコンパイルエラーになってたのに。なんなんだ。


参考:
http://stackoverflow.com/questions/25360127/intstream-strange-error

2015年2月6日金曜日

クロスドメインでAjax、なおかつセッション情報も利用するなら・・・

クロスドメインでAjaxを使うのには、レスポンスヘッダーに

Access-Control-Allow-Origin:http://allowed-origin.test

てな感じで許可をつけてやらねばならないというのは前に書いた。

このオリジンというのはポート番号まででパスは不要、というか、リクエストヘッダーのOriginとして送られてきたものを(許可できるなら)戻すのが本筋のようだ。


で、自分がやりたいのは自サイト内部のHTTPからHTTPSへのクロスなのであり、そんなことをしたい理由はもちろん認証情報の取得だ。つまり、Cookieがいる。

が、クロスサイトなAjaxを上記で許可した場合、通信自体は許可されるが諸々の制限がついていて、Cookie、それからX-の拡張ヘッダ類は送られない。

受け取っていいヘッダを、


Access-Control-Allow-Headers:X-Foo,X-Bar

てな感じで書いてやらねばならない。これがないと、jQueryなんかがつけてくれるX-Requested-Withヘッダーなんかもつかない。


Cookieも送りたいので上記にCookieと書けばいいかというと、それではだめで、Cookieを送るには、XMLHttpRequestにwithCredentialプロパティをtrueで設定しないとならない。Cookieは認証に使われるからか、特別扱いなわけかね。

で、これを具体的に行う方法が、たとえばjQueryでは、こうなる。


jqTargetなるjQueryオブジェクトが、取得したコンテンツをロードしたい対象だとしたら、

$.ajax({
url: loadUrl,
xhrFields: {
withCredentials: true
}
}).done(function(data){
jqTarget.html(data);
});


通常なら、jqTarget.load(loadUrl);で終わるところだが。

(オリジンを許可してない場合、どっちにしろつながりもしない。この場合、ChromeのデバッガではOPTIONメソッドの履歴が残り、利用できる応答がないとかそういうことになってる。OPTIONなって使ってねーよ!と思うが、これはプリフライトと呼ばれる、クロスドメインのXMLHttpでのネゴシエート的なものの結果のようだ)




参考:

  • https://developer.mozilla.org/ja/docs/HTTP_access_control
  • http://dev.classmethod.jp/etc/about-cors/

2015年2月5日木曜日

クロスドメインのAjaxだとX-Requested-Withてついてくれないんですか?

そもそもこのヘッダ、なんでついてるのかもよく確認せず使ってましたが、jQueryがつけてくれてるだけなんですね。

で、自分の作ってたサイトで、http -> httpsでAjaxを使いたいのでAccess-Control-Allow-Originを使って通信したところ、X-Requested-Withがついてこないもので、これを見ていた自前のサーバーサイド検査 request.isXmlHTTP()が引っかかってしまった。

ただ、そもそもサーバーサイドの処理がjQueryに依存しているというのはおかしな感じがしていやだし、他にも微妙な問題がありそうなんで、Ajaxかどうか?の検査にはこのヘッダーを見るのではない代案を考えようと思う。

どうせ偽装可能なヘッダ情報なんだから、Refererとかでもいいのか・・・それとも、そもそもこんな検査にこだわらない(セキュリティの一助になればという思いだったが、もっと別の手を考える)方がいいのか・・・。

PHPって怖ろしいんだな・・・

http://d.hatena.ne.jp/ockeghem/20110905/p1

・・・こんなことがあるなんて。ちゃんとした出版社から出てる教科書なのに・・・。

って、まあ、このレベルをPHP開発者全員に当てはめたら怒られるんだろうけど。それに、JavaScriptの非同期通信を使った部分のセキュリティ確保については自分もよくわからないところが多く、それでアレコレ検索してたらこういうページにたどり着いたんだしね。

他人を笑えるほどわかってはいないか、俺も。まあ、だから俺は本は書いてないけど。