タイトル:セッションベースの共有とシングルサインオンのSpringBoot + Redisの
DATE:2019年7月23日午前2時55分52秒
カテゴリー:
- アーキテクチャ
著者:mrzhou
タグ: - SpringBoot
- 繰り返します
- セッション
シングルサインオン
シングルサインオンとSpringBoot + Redisのベースのセッション共有
序文
Redisのは、実際には、インターネットは、多くの例があり、セッション共有を使用して実装され、これは、そのクラスタの展開Redisの最も典型的な使用シナリオを確保することです。SpringBootプロジェクトでは、実際には、あなたは、単に(もちろん、構成情報がまだ必要とされている)の注釈を追加するための行を追加し、依存性を達成することができ、行を記述することなく、コードを実行することができます。
プロジェクトは、単にそのような別のポート(A、B)のように、異なるTomcatに展開するが、アクセスパスが同一のプロジェクトです。この時に使用する設定方法、及びその後BでGETメソッドを使用し、Bは、コンテンツのセットを取得することができるAに見出すことができます。
複数のTomcatに配備入れ、そのようなプロジェクトは、シングルサインオンを実現するために言われている場合しかし、それは間違っているだろう。
いわゆるシングルサインオン別のプロジェクトを参照して、あなただけの任意のプロジェクトにログインし、ログインするために必要な他のプロジェクトが必要です。
同様に上記の例で、我々は、設定された2つのメソッドを有し、二つのアイテムを取得する(設定、取得する)配置され、2つのクラスタ内の方法は、それぞれ、サーバプロジェクトAとBに展開し、次にサーバAにアクセスされていますセットとBのサーバーを取得し、あなたが望む正確な結果を見つけることができません。
同じプロジェクトの設定/取得
追加は、最も簡単な方法を指示し、言わない依存します
@SpringBootApplication
@EnableRedisHttpSession
@RestController
public class SessionShareApplication {
public static void main(String[] args) {
SpringApplication.run(SessionShareApplication.class, args);
}
@Autowired
HttpSession session;
@Autowired
HttpServletRequest req;
@GetMapping("/set")
public Object set() {
session.setAttribute("state", "state was setted.");
Map<String, Object> map = new TreeMap<>();
map.put("msg", session.getAttribute("state"));
map.put("serverPort", req.getLocalPort());
return map;
}
@GetMapping("/get")
public Object get() {
Map<String, Object> map = new TreeMap<>();
map.put("msg", session.getAttribute("state"));
map.put("serverPort", req.getLocalPort());
return map;
}
}
戦争のパッケージを再生する項目は、その後、セッションの値を取得するメソッドを取得/ tomcatBを使用し、tomcatA(ポート8080)、tomcatB(ポート8081)で展開した後、tomcatA / setメソッドセッションで設定されています。しかし、これは、同じプロジェクトの共有セッションを達成しています。ないシングルサインオン。
検証のために、我々は2つのプロジェクトのためのスプリット設定/ getメソッドを模倣しません。
スプリットセット/二つのプロジェクトを取得
- プロジェクトを取得
@SpringBootApplication
@EnableRedisHttpSession
@RestController
public class SetApplication {
public static void main(String[] args) {
SpringApplication.run(SetApplication.class, args);
}
@Autowired
HttpSession session;
@Autowired
HttpServletRequest req;
@GetMapping("/")
public Object set() {
session.setAttribute("state", "state was setted.");
Map<String, Object> map = new TreeMap<>();
map.put("msg", session.getAttribute("state"));
map.put("serverPort", req.getLocalPort());
return map;
}
}
プロジェクトはset.warとしてパッケージ化されました
- セットプロジェクト
@SpringBootApplication
@EnableRedisHttpSession
@RestController
public class GetApplication {
public static void main(String[] args) {
SpringApplication.run(GetApplication.class, args);
}
@Autowired
HttpSession session;
@Autowired
HttpServletRequest req;
@GetMapping("/")
public Object get() {
Map<String, Object> map = new TreeMap<>();
map.put("msg", session.getAttribute("state"));
map.put("serverPort", req.getLocalPort());
return map;
}
}
プロジェクトはget.warとしてパッケージ化され
、その後set.warは、その後、tomcatA /セットすることで、セッションを設定し、tomcatAとtomcatBに展開get.warし、その後tomcatBで/それはそれは不可能セッションの値を取得することが分かっます。
分析
我々が使用するパスが同じであるが、二つのプロジェクト、実際には、プロジェクトの前では完全に異なっているが、問題は、デフォルトでは、セッションクッキーとは、プロジェクトのパス、同じ状況で、プロジェクトに関連していることですクッキーパス依存プログラムは、問題がないように、セッションの値を取得する、2つの方法が同じである必要はなく、後者の場合には、クッキーのパスは、異なるアイテムへ2番目の項目に属し設定セッションの内容最初のプロジェクトを取得することができません。
ソリューション
実際には、解決策はspringbootプロジェクトでは非常に簡単です。クッキーのパスが変更されているので、我々はそれが同じパスに解決されるように構成することができます。
以下のような構成では、各サブプロジェクトに追加またはドメイン名はまた、set.xxx.comとget.xxx.comこの場合のように、制限のドメイン名を設定することができます持っていると私たちはクッキードメイン名を設定する必要がある場合は、直接、クッキーのパスを設定していますxxx.comとして、クッキー値xxx.comドメイン名の下のアイテムを取得することはできませんようにします。これは、セッションの共通の価値観への定期的なアクセスを確保します。
@Configuration
public class CookieConfig {
@Bean
public static DefaultCookieSerializer defaultCookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookiePath("/");
//serializer.setDomainName("xxx.com"); //如果使用域名访问,建议对这一句进行设置
return serializer;
}
}
上記正直Redisのは、シングルサインオンを実現するオープンする正しい方法です。