(Java)Tomcat:クロスドメインセッションを行う

タスクの説明:


TomcatでJavaプロジェクトを実行しています。 そして、サイトのセクションをサブドメインの形で整理することにしました。
たとえば、ウェブサイトwww.domain.xxでセクションを作成します: mail.domain.xxuser.domain.xxなど。 開発のある時点で、予想に反して、ユーザーセッションが厳密に同じドメイン内に存在することに驚くでしょう。 つまり、ユーザーがメインページ( www.domain.xx )にログインしてメール( mail.domain.xx )を渡すと、認証が失われます。

実際、セッションは、 JSESSIONIDという名前と空のドメインを持つCookieを介してクライアントにバインドされます。 ドメインが指定されていない場合、ブラウザは現在のドメイン全体を使用します。 つまり、セッションは「domain.xx」ではなく「www.domain.xx」に関連付けられています。 私には不明な理由で、この動作を制御するTomcatの設定はありません。



処理方法:


まず、セッションについてもう少し。 セッションは、request.getSession()メソッドを呼び出すことによって取得されます。 メソッド内では、JSESSIONID Cookieが読み取られ、対応するセッションが「ストア」から取得されます。 セッションがない場合、セッションが作成され、新しいJSESSIONID値を持つCookieが応答ヘッダーに書き込まれます。 ここが表示されます! 必要なのは、目的のドメイン値( domen.xx )をcookieに追加することだけです。

TomcatはValveメカニズムを提供します。 実際、バルブは各リクエストが処理される前に呼び出されるjavaクラスです。 読者が推測するように、実装で使用されるのはこのメカニズムです。 各リクエストを処理する前にセッションを処理するValveクラスを作成する必要があります。 セッションが作成されたばかりの場合は、Cookieを置き換えます。

実装:


バルブクラス:

package my.tomcat;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;

import org.apache.catalina.Globals;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;
import org.apache.tomcat.util.http.ServerCookie;

public class SubdomainSessionValve extends ValveBase {

/** */
private static final String DOMAIN = "domain.xx" ;

@Override
public String getInfo() {
return "my.tomcat.SubdomainSessionValve/1.0a" ;
}

@Override
public void invoke(Request req, Response res)
throws IOException, ServletException {

fixSessionIdCookie(req);

getNext().invoke(req, res);
}

private void fixSessionIdCookie(Request request) {
if (getJsessionCookie(request.getCookies()) != null )
return ;

request.getSession();

Cookie cookie = getJsessionCookie(request.getResponse().getCookies());
if (cookie == null )
return ;

cookie.setDomain(DOMAIN);

StringBuffer sb = new StringBuffer();
ServerCookie.appendCookieValue(sb,
cookie.getVersion(), cookie.getName(), cookie.getValue(),
cookie.getPath(), cookie.getDomain(), cookie.getComment(),
cookie.getMaxAge(), cookie.getSecure());

request.getResponse().setHeader( "Set-Cookie" , sb.toString());
}


Cookie getJsessionCookie(Cookie[] cc) {
for ( int i = 0; cc != null && i < cc.length; i++) {
if (Globals.SESSION_COOKIE_NAME.equals(cc[i].getName()))
return cc[i];
}
return null ;
}
}


* This source code was highlighted with Source Code Highlighter .


このクラスのjarを$ {TOMCAT_HOME} / server / libに配置し、server.xmlに書き込むことは残ります。

<Valve className = "my.tomcat.SubdomainSessionValve" />

または、アプリケーションからサーバーを起動する場合:

org.apache.catalina.Context context;

....... //

context.getPipeline().addValve( new my.tomcat.SubdomainSessionValve());


* This source code was highlighted with Source Code Highlighter .


ご清聴ありがとうございました。
頑張って

Source: https://habr.com/ru/post/J51266/


All Articles