シングルサインオンを実現するために、asp.net MVCのセッションを使用する代わりに、JWT

ASP.NET MVCの代わりにシングルサインオンを実現するために、JWTのセッションを使用しての
トークンは何1.?
2. JWTは何ですか?
トークンは、セッションとの比較3.
シングルサインJWT実装する方法4. ASP.NET MVC
1.トークンは何ですか?
トークンとは何ですか?トークンは、一般的に、コンピュータのID認証に使用するトークン、として理解することができます。データ・サーバを転送する前に、本人確認。

2. JWTは何ですか?
JWTは何ですか?JWT短いため、JSONウェブトークンである、それはトークン仕様です。ABCの文字列が暗号化された後、一部。ストリングは、トークンの暗号化、ストリング(パートA)の長さは、基本的なユーザ情報、ペイロード、発行者、有効期限(パートB)、及び共通暗号化部分A及びB(パートC)を構成して記録されています。

セッション3.トークン比較
にさらさ問題の伝統的なセッション
セッション:コンピュータサーバーのメモリ内のユーザー識別認証がセッションを保存するたびにした後、クライアントは、次のユーザー要求で本人確認のために、クッキーを保存します。しかし、これは二つの問題を公開しています。ユーザー要求の数は、サーバーが圧力を増加させるとき、最初の問題は、セッションは、サーバー上のメモリに格納されています。第二の問題は、分散開発には適用されませんだけで、単一のサーバ、現在のセッションに複数のサーバ、およびストレージを持っている場合ということです。

CSRF:クッキーが傍受された場合、ユーザーは、クロスサイトリクエストフォージェリ攻撃に対して非常に脆弱であるユーザ識別に基づいて、セッションクッキー、我々はCSRF(クロスサイトリクエストフォージェリ)考えていません。

トークン認証メカニズム
トークン認証ユーザーが分散開発を支援する複数のサーバへの単一のアクセスポイントを介して、クライアントにして、ログインしたときように、サーバ側で任意のユーザの情報を保持する必要があります。トークン文字列と文字列が暗号化され、有効期限を設定することができ、それが簡単に真似することはできません。

トークン、クライアントとサーバーの対話プロセスを使用して、次のようにおおよそ次のとおりです。

サーバへのユーザからユーザ名とパスワードが要求し
たユーザ情報を認証するためにサーバを
ユーザ認証にトークンを介してサーバを
クライアントトークンメモリ、および上のトークン値に含まれる各要求
サーバー認証トークン、およびデータを返す
トークンを保存することができますクッキーにも、リクエストヘッダに格納することができ、それはリクエストヘッダにトークン及びトークンは、MACアドレスとコンピュータ名を運ぶことをお勧め。

4. ASP.NET MVCシングルサインオンを実装する方法をJWT
クラスUserStateを定義

名前空間LYQ.TokenDemo.Models.Infrastructure
{
publicクラスUserState
{
公共の文字列のユーザー名{取得します。セットする; }
パブリック文字列のユーザーID {得ます。セットする; }
公共のint型のレベル{取得します。セットする; }
}
}

定义一个のAppManager类和TokenInfo类

パブリック静的UserStateのUserState
{
取得
{
のHttpContextのHttpContext = HttpContext.Current。
VARクッキー= httpContext.Request.Cookies [Key.AuthorizeCookieKey]。
VAR tokenInfo =クッキー?.Valueの?? "";
//トークン解密
VAR encodeTokenInfo = TokenHelper.GetDecodingToken(tokenInfo)。
UserState userState = JsonHelper <UserState> .JsonDeserializeObject(encodeTokenInfo)。
userStateを返します。
}
}

publicクラスTokenInfo
{
パブリックTokenInfo()
{
ISS = "LYQ"。
IAT =(DateTime.UtcNow -新規のDateTime(1970、1、1、0、0、0、DateTimeKind.Utc))TotalSeconds;。
EXP = IAT + 300。
AUD = "";
サブ=「LYQ。
JTI = "LYQ。" + DateTime.Now.ToString( "YYYYMMDDHHMMSS")。
}

公共の文字列ISS {取得します。セットする; }
公共ダブルIAT {得ます。セットする; }
公共の二重のexp {取得します。セットする; }
パブリック文字列AUD {得ます。セットする; }
公共ダブルNBF {得ます。セットする; }
パブリック文字列サブ{得ます。セットする; }
パブリック文字列JTI {得ます。セットする; }

}

定義JsonHelper

T <T>パブリッククラスJsonHelper:クラス
{
パブリック静的T JsonDeserializeObject(文字列JSON)
{
JsonConvert.DeserializeObject <T>(JSON)を返します。
}

JsonSerializeObject静的ストリングパブリック(オブジェクトobj)
{
JsonConvert.SerializeObject(OBJ)を返す;
}
}

ホームコントローラログインメソッドを定義

[HTTPGET]
[LYQ.TokenDemo.Models.CustomAttribute.Authorize(偽)]
公共のActionResultログイン()
{
()表示を返します。
}

[HttpPost]
[LYQ.TokenDemo.Models.CustomAttribute.Authorize(偽)]
公共のActionResultログイン(文字列アカウント、文字列のパスワード)
{
場合(アカウント== "ティム" &&パスワード== "ABC123")
{
VARクッキー=新しいHttpCookie (Key.AuthorizeCookieKey、TokenHelper.GenerateToken())。
HttpContext.Response.Cookies.Add(クッキー);
リターンJSON( "Y")。
}

{
VARクッキー=新しいHttpCookie(Key.AuthorizeCookieKey、 "");
HttpContext.Response.Cookies.Add(クッキー);
リターンJSON( "N")。
}
}

生成トークン
使用NuGet、下载JWT.dll

LYQ.TokenDemo.Models名前空間
{
publicクラスTokenHelper
{
// JWT秘密鍵は、解放できない
民間のconst文字列のSecretKey = "LYQ.abcqwe123を" 。

パブリック静的文字列GenerateToken()
{
VARのtokenInfo =新しいTokenInfo()。
VARペイロード=新しい辞書<文字列、オブジェクト>
{
{ "ISS"、tokenInfo.iss}、
{ "IAT"、tokenInfo.iat}、
{ "EXP"、tokenInfo.exp}、
{ "AUD"、tokenInfo.aud} 、
{ "サブ"、tokenInfo.sub}、
{ "JTI"、tokenInfo.jti}、
{ "userNameに"、 "ティム"}、
{ "ユーザID"、 "001"}、
{ "レベル"、18}
}。

IJwtAlgorithmアルゴリズム=新しいHMACSHA256Algorithm();
IJsonSerializerシリアライザ=新しいJsonNetSerializer();
IBase64UrlEncoderのURLEncoder =新しいJwtBase64UrlEncoder();
IJwtEncoderエンコーダ=新しいJwtEncoder(アルゴリズム、シリアライザ、のURLEncoder)。

VARトークン= encoder.Encode(ペイロード、のSecretKey)。
トークンを返します。
}

公共の静的な文字列GetDecodingToken(文字列strToken)
{
しようと
{
IJsonSerializerシリアライザ=新しいJsonNetSerializer();
IDateTimeProviderプロバイダ=新しいUtcDateTimeProvider();
IJwtValidatorバリ=新しいJwtValidator(シリアライザ、プロバイダ)。
IBase64UrlEncoderのURLEncoder =新しいJwtBase64UrlEncoder();
IJwtDecoderデコーダ=新しいJwtDecoder(シリアライザ、バリデータ、のURLEncoder)。

JSON decoder.Decode = VAR(strToken、のSecretKeyは、確認:trueに)、
JSONを返す;
}
キャッチ(例外)
{
リターン"";
}
}
}
}

カスタム認証は
、本明細書にので、ここでカスタム認証モードを取られますそれはAuthorizeAttributeを定義します。

名前空間LYQ.TokenDemo.Models.CustomAttribute
{
publicクラスAuthorizeAttribute:FilterAttribute、IAuthorizationFilter
{
公共AuthorizeAttribute(BOOL _isCheck = TRUE)
{
this.isCheck = _isCheck。
}

プライベートブールisCheck {取得します。}

公共ボイドOnAuthorization(AuthorizationContext filterContext)
{
VARのHttpContext = filterContext.HttpContext。
VAR actionDescription = filterContext.ActionDescriptor。

(actionDescription.IsDefined(typeof演算(AllowAnonymousAttribute))、偽||場合
actionDescription.ControllerDescriptor.IsDefined(typeof演算(AllowAnonymousAttribute))、偽){返します。}

(!isCheck)であればリターン。

IF(AppManager.UserState == NULL)
{
IF(httpContext.Request.IsAjaxRequest())
{
filterContext.Result化するJsonResult新しい新=()
{
データ新しい新しい= {ステータス= "失敗"、メッセージ= "403 Forbin"は、=のStatusCode " 403 "}、
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}

{
filterContext.Result RedirectResult新しい新=((" /ホーム/ログイン「));
}
}

{
//新しいトークン再たことに応答して、各認証後渡しクライアントへの
VAR =新しい新しいクッキーHttpCookie(Key.AuthorizeCookieKey、TokenHelper.GenerateToken());
filterContext.HttpContext.Response.Cookies.Add(クッキー);
}
}
}
}

HTMLページ

@ {
ViewBag.Title = "ログイン";
}

<リンクのhref = "〜/コンテンツ/ bootstrap.min.css" のrel = "スタイルシート" />

<H2>これは、ログインページです。</ H2>

<DIV CLASS = "コンテナ">
<フォームクラス= "ボックス・ボディ"アクション= "/ホーム/ログイン"メソッド= "ポスト">
<DIV CLASS = "フォーム・グループ行">
<ラベルクラス= "COL-SM -1 COL-MD-1 ">アカウント:</ label>は
<DIV CLASS =" COL-SM-5 COL-MD-5 ">
の<input type =" text "クラス= "フォームコントロール" ID ="アカウント"名前="アカウント」/>
</ div>
</ div>
<DIV CLASS = "フォームグループ行">
<ラベルクラス= "COL-SM-1 COL-MD-1">パスワード:</ラベル>
<DIV CLASS = "COL-SM-5 COL-MD-5">
の<input type = "パスワード"クラス= "フォームコントロール" ID = "パスワード" NAME = "パスワード"/>
</ div>
</ div>
<DIV CLASS = "フォームグループ行">
<DIV CLASS = "COL-SM-1 COL-MD-1"> </ div>
<DIV CLASS = "COL-SM -5 COL-MD-5" >
<ボタンタイプ= "ボタン"クラス= "BTN BTN-INFO"のonclick = "ログイン();">ログイン</ボタン>
<ボタンタイプは、クラス= "BTN BTN-INFO"を"リセット" =>リセット</ボタン>
</ div>
</ div>
<DIV CLASS = "フォームグループ行">
<DIV CLASS = "COL-SM-1 COL-MD-1"> </ div>
<DIV CLASS = "COL-SM-5 COL-MD-5" >
<span>のアカウント:ティム。パスワード:abc123を</ span>を
</ div>
</ div>
</ FORM>

</ div>

<スクリプトSRC = "〜/スクリプト/ jqueryの-3.3.1.min.js"> </ SCRIPT>
<スクリプトSRC = "〜/ StaticFiles /フロントエンド/スクリプト/ Common.js"> </ SCRIPT>

<スクリプト>

関数ログイン(){
VARのパラグラフ=
{
アカウント:$( "#アカウント")のval()、。
パスワード:$( "#パスワード")のval()
};

LYQ.sendAjaxRequest({
タイプ: "ポスト"、
URL: "/ホーム/ログイン"、
PARAM:パラス、
データ型: "JSON"、
コールバック:機能(結果){
場合(結果== "Y"){
はconsole.log ( "ログイン成功")、
警告( "ログイン成功");
window.locationの= "/";
}他{
にconsole.log( "ログインが失敗")、
警告( "ログイン失敗");
}
}
})。
}

</ SCRIPT>

Common.js

!(関数(ウィンドウ){
VAR関数= {
sendAjaxRequest:機能(optsの){
VARの自己=この;
$アヤックス({
タイプ:opts.type || "ポスト"、
URL:opts.url、
データ:opts.param || {}、
のcontentType:opts.contentType ===ヌル真:opts.contentType、
キャッシュ:opts.cache ===ヌル真:opts.cache、
PROCESSDATA:opts.processData ===ヌル真:オプト.processData、
beforeSend:機能(XMLHttpRequestを){
XMLHttpRequest.setRequestHeader(LYQ.getAuthorizationKey()、 "");
}、
データ型:opts.dataType || "JSON"、
成功:関数(結果){
(のObject.prototype場合。 toString.call(opts.callBack)=== "[目的関数]"){//判断コールバック是否の是機能
opts.callBack(結果)。
} {他
にconsole.log(「コールバック関数ではありません」)。
}
}
})。
}、
getRequestHeaderAuthorizationToken:関数(){
VARのdocument_cookie = document.cookie。
//するvar REG =新しい正規表現( "(^ |)" +名+ "=([^;] *)(; | $)");
//(document_cookie = document.cookie.match(REG))の場合
アンエスケープを戻す//(ARR [2])。
//それ以外
はnullを返します//;
console.log(document_cookie)。
document_cookieを返します。
}、
getAuthorizationKey:関数(){
リターン'許可';
}
}。

= window.LYQ機能;
})(
これは); ----------------
免責事項:この記事はCSDNブロガーである「私李勇銭銭銭銭銭」元記事で、CCをたどります再現4.0 BY-SA著作権契約、元のソースのリンクと、この文を添付してください。
オリジナルリンクします。https://blog.csdn.net/weixin_44308006/article/details/90459801

おすすめ

転載: www.cnblogs.com/666www/p/11686565.html