シングルサインオンの3つの方法:ステートレスプロトコル+セッションメカニズム+ログインメカニズム。

序文

シングルサインオンは、httpステートレスプロトコル、セッションメカニズム、ログインメカニズムの3つのメカニズムに分けられます。

httpステートレスプロトコル

Webアプリケーションはブラウザ/サーバーアーキテクチャを使用します。httpは通信プロトコルとしてhttpはステートレスプロトコルであり、各ブラウザリクエストは、次の図に示すようにサーバーが個別に処理されます。3つのリクエストとレスポンスの間に関係はありません。 。

シングルサインオンの3つの方法:ステートレスプロトコル+セッションメカニズム+ログインメカニズム。

 

つまり、上の図によれば、httpリクエストはステートレスプロトコルです。

セッションメカニズム

ブラウザが初めてリクエストサーバーにアクセスすると、サーバーはセッションを再度作成し、データをブラウザに送信します。ブラウザはセッションIDを保存し、サーバーはIDによってリクエストからユーザーであるかどうかを判断します。

シングルサインオンの3つの方法:ステートレスプロトコル+セッションメカニズム+ログインメカニズム。

 

サーバーはセッションオブジェクトをメモリに保存しますが、ブラウザはどのようにセッションIDを保存しますか?あなたは2つの方法を考えるかもしれません

  1. リクエストパラメータ
  2. Cookie 
    は、各リクエストのパラメータとしてセッションIDを受け取ります。サーバーはリクエストを受信し、パラメータを自然に解析してセッションIDを取得し、同じセッションからのものかどうかを判断できます。明らかに、この方法は信頼できません。次に、ブラウザはこのセッションIDを自動的に維持します。ブラウザは、httpリクエストが送信されるたびに、セッションIDを自動的に送信します。これを行うためにCookieメカニズムが使用されます。Cookieは、ブラウザが少量のデータを保存するために使用するメカニズムです。データは「キー/値」の形式で保存され、ブラウザがhttpリクエストを送信するとCookie情報が自動的に添付されます。

もちろん、TomcatセッションメカニズムもCookieを実装しています。Tomcatサーバーにアクセスすると、ブラウザに「JSESSIONID」という名前のCookieが表示されます。これはTomcatセッションメカニズムによって維持されるセッションIDです。Cookieを使用したリクエスト応答プロセスが表示されます。下の図で。

シングルサインオンの3つの方法:ステートレスプロトコル+セッションメカニズム+ログインメカニズム。

 

ログインステータス

セッションメカニズムでは、ログイン状態は、ブラウザが最初にサーバーにIDの確認を要求するときに、ブラウザがIDを確認するためにユーザー名とパスワードを入力する必要があることを前提としています。セッションを保持しているユーザーは正当なユーザーであり、セッションは正当なユーザーである必要があります。承認済みまたはログイン済みとしてマークされます。ロゴは以下の通りです。

HttpSession session = request.getSession();
session.setAttribute("isLogin", true);

ユーザーが再度アクセスすると、次のログインステータスが表示されます

HttpSession session = request.getSession();
session.getAttribute("isLogin");

実装されたモデルは次のとおりです。

シングルサインオンの3つの方法:ステートレスプロトコル+セッションメカニズム+ログインメカニズム。

 

保護されたリソースが要求されるたびに、セッションオブジェクトのログインステータスがチェックされます。isLogin= trueのセッションにのみアクセスできるため、ログインメカニズムが実装されます。

実装方法の説明から始めましょう

それを達成する1つの方法:親ドメインCookie

Cookieのスコープは、ドメイン属性とパス属性によって決定されます。ドメイン属性の有効な値は、現在のドメインまたはその親ドメインのドメイン名/ IPアドレスです。Tomcatでは、ドメイン属性はデフォルトで現在のドメインのドメイン名/ IPアドレスになります。path属性の有効な値は、「/」で始まるパスです。Tomcatでは、path属性はデフォルトで現在のWebアプリケーションのコンテキストパスになります。

Cookieのドメイン属性が現在のドメインの親ドメインに設定されている場合、それは親ドメインCookieと見なされます。Cookieには、親ドメインのCookieが子ドメインによって共有されるという特性があります。つまり、子ドメインは親ドメインのCookieを自動的に継承します。

Cookieのこの機能を使用すると、セッションID(またはトークン)を親ドメインに保存するだけでは不十分であると考えるのは難しくありません。そうです、Cookieのドメイン属性を親ドメインのドメイン名(メインドメイン名)に設定し、同時にCookieのパス属性をルートパスに設定するだけで、すべてのサブドメインアプリケーションがクッキーにアクセスできます。ただし、これには、アプリケーションシステムのドメイン名を、tieba.baidu.comやmap.baidu.comなどの共通のメインドメイン名で確立する必要があります。これらは両方ともbaidu.comのメインドメイン名で確立されます。その後、この方法を通過して、シングルサインオンを実現できます。

実施方法2:認証センター

これらの問題に対処するために認証センターを展開できます

ユーザーは認証センターにログインします。ログインが成功すると、認証センターはユーザーのログインステータスを記録し、トークンをCookieに書き込みます。

アプリケーションシステムは、現在のリクエストにトークンがあるかどうかを確認します。ない場合は、ユーザーが現在のシステムにログインしていないことを意味し、ページは認証センターにリダイレクトされます。この操作により、認証センターのCookieが自動的に取得されるため、認証センターは、ユーザーがCookieに従ってログインしたかどうかを知ることができます。認証センターは、ユーザーがログインしていないことを検出すると、ログインページに戻り、ユーザーがログインするのを待ちます。ユーザーがすでにログインしていることを検出した場合、ユーザーは再度ログインできません。ただし、ジャンプトークンがターゲットURLの背後でスプライスされ、ターゲットアプリケーションシステムに返送される前に、ターゲットURLにジャンプして戻り、ジャンプトークンを生成します。

アプリケーションシステムはトークンを取得した後、ユーザーがトークンを偽造できないように、認証センターにトークンの合法性を確認する必要もあります。確認が正しいと、アプリケーションシステムはユーザーのログインステータスを記録し、トークンをCookieに書き込んでから、訪問を解放します。(このCookieは現在のアプリケーションシステムにあり、他のアプリケーションシステムからはアクセスできないことに注意してください。)ユーザーが現在のアプリケーションシステムに再度アクセスすると、このトークンが自動的に取得されます。アプリケーションシステムはトークンを確認し、ユーザーがログインしているので、認証センターはどうなりましたか?

よく知られている認証センターはApereoCASです。XXL-SSO

LocalStorageクロスドメインの実装

複数のドメインでセッションID(またはトークン)を共有する方法。

親ドメインCookieは確かに優れたソリューションですが、クロスドメインをサポートしていません。では、Cookieをドメイン間で受け渡すための秘訣はありますか?

残念ながら、ブラウザではCookieに対するクロスドメインの制限がますます厳しくなっています。ChromeブラウザはCookieにSameSite属性も追加します。これにより、クロスドメインリクエスト(ハイパーリンクを除く)のCookieの送信がほぼ禁止され、HTTPSプロトコルが使用されている場合にのみ、AJAXクロスドメインリクエストでCookieを許可できます。サーバ。

ただし、フロントエンドとバックエンドが分離されている場合、Cookieは完全に不要です。セッションID(またはトークン)をブラウザのLocalStorageに保存することを選択できるため、フロントエンドが主導権を握ってLocalStorageを保存します。リクエストがバックエンドに送信されるたびに、データはサーバーに渡されます。これらはすべてフロントエンドによって制御されます。ユーザーが正常にログインした後、バックエンドが行う必要があるのは、応答本文のセッションID(またはトークン)をフロントエンドに渡すことだけです。

このようなシナリオでは、シングルサインオンをフロントエンドに実装できます。フロントエンドがセッションID(またはトークン)を取得した後、それを独自のLocalStorageに書き込むだけでなく、特別な方法で他の複数のドメインの下のLocalStorageに書き込むこともできます。

サンプルコードは次のとおりです。

// 获取 token
var token = result.data.token;

// 动态创建一个不可见的iframe,在iframe中加载一个跨域HTML
var iframe = document.createElement("iframe");
iframe.src = "http://app1.com/localstorage.html";
document.body.append(iframe);
// 使用postMessage()方法将token传递给iframe
setTimeout(function () {
    iframe.contentWindow.postMessage(token, "http://app1.com");
}, 4000);
setTimeout(function () {
    iframe.remove();
}, 6000);

// 在这个iframe所加载的HTML中绑定一个事件监听器,当事件被触发时,把接收到的token数据写入localStorage
window.addEventListener('message', function (event) {
    localStorage.setItem('token', event.data)
}, false);

フロントエンドはiframe + postMessage()を使用して、同じトークンを複数のドメインのLocalStorageに書き込みます。フロントエンドがバックエンドにリクエストを送信するたびに、ローカルストレージからトークンをアクティブに読み取り、リクエストで運びます。 。同じトークンが複数のドメインで共有されます。

誰もがシングルサインオンを学ぶのに役立つことを願っています。私が好きな友達が転送とフォローを手伝ってくれることを願っています。ありがとう!

おすすめ

転載: blog.csdn.net/Ppikaqiu/article/details/112791747