shiro2.1_認(rèn)證

1

2

認(rèn)證就是身份驗(yàn)證的過程,具體來說就是證明一個用戶的真實(shí)身份和用戶所描述的身份一致的過程蒜鸡。當(dāng)驗(yàn)證一個用戶身份的時候馆衔,需要用戶提供一些身份信息就比如系統(tǒng)可以理解的結(jié)構(gòu)化的數(shù)據(jù)。

這個過程通過提交一個用戶的principal和credential給shiro判斷是否匹配應(yīng)用內(nèi)部期望的信息來完成的扭弧。

  • principal是一個用戶的身份屬性,principal可以有多個,可以是任何可證明用戶身份的東西,比如系統(tǒng)名(由系統(tǒng)給定的名稱),昵稱(用戶自定義名),用戶手機(jī)號,社保號碼,等等.當(dāng)然有些內(nèi)容并不適合作為principal,比如用戶實(shí)際的姓名,因?yàn)楝F(xiàn)實(shí)中重名的概率極大,最好的principal必須是唯一的,比如用戶的身份證號或者郵箱地址.
主principal

Shiro中可以存在任意數(shù)量的principal,但推薦一個應(yīng)用程序只接受一個主要的principal,一個在應(yīng)用中唯一存在的值對應(yīng)一個principal.這也是在大多數(shù)應(yīng)用中經(jīng)常使用的用戶名,郵箱地址或者全局唯一用戶id等單一principal認(rèn)證方式.

  • credential通常是加密后的數(shù)據(jù),只和principal相關(guān)的內(nèi)容,總是被用來校驗(yàn)身份是否屬實(shí).通常的實(shí)例是密碼,生物數(shù)據(jù)數(shù)據(jù)比如指紋信息,視網(wǎng)膜掃描,和X.509格式的證書等.

比較常見的principal/credential對是用戶名和密碼.用戶名就是聲明的信息,密碼就是聲明的信息和系統(tǒng)內(nèi)部是否匹配的證明.如果提交的密碼與內(nèi)部存儲的期望的信息匹配就足以說明此用戶為真.


3

用戶證明

用戶認(rèn)證過程可以被分為三個步驟:

  1. 收集用戶提交的principal和credential
  2. 提交收集到的信息
  3. 如果后臺驗(yàn)證成功,則允許使用系統(tǒng)其它功能,否則需要重新認(rèn)證或者禁止認(rèn)證
    接下來的代碼演示了如何使用Shiro的API實(shí)現(xiàn)上述步驟:


    4

第一步: 收集用戶的principal和credential

// 通常情況下使用用戶名密碼進(jìn)行安全認(rèn)證的例子
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
// 自帶記住我的功能
token.setRememberMe(true);

在此案例中,我們使用了UsernamePasswordToken類,支持最常見的用戶名/密碼的身份認(rèn)證方式.這個類實(shí)現(xiàn)了Shiro里面的org.apache.shiro.authc.AuthenticationToken接口,AuthenticationToken接口的任意實(shí)現(xiàn)都可以被Shiro的認(rèn)證系統(tǒng)獲取此系統(tǒng)的使用者提交的principal和credential.

有一點(diǎn)很重要,Shiro根本不關(guān)心你是如何獲取這些信息的,或許這些數(shù)據(jù)信息是一個用戶通過html表單里面提交的,或者它檢索自一個HTTP頭信息,又或者它來源于一個Swing/Flex GUI密碼表單,又或者僅僅是命令行的參數(shù).從終端用戶那里收集信息的過程與認(rèn)證用戶身份的過程是完全分離的.

你可以隨意構(gòu)造和創(chuàng)建AuthenticationToken對象實(shí)例-它與協(xié)議無關(guān)

此示例還表明,我們已經(jīng)表示希望Shiro為身份驗(yàn)證嘗試執(zhí)行'Remember Me'服務(wù).這就保證了Shiro記住此用戶的登錄信息,同時可以在用戶一段時間后再次使用此應(yīng)用時無需重復(fù)登錄.我們將在之后的章節(jié)介紹Remember Me(記住我)服務(wù).


5
第二步:提交principal和credential

在principal和credential收集成功并創(chuàng)建了一個AuthenticationToken對象實(shí)例后,我們需要提交此令牌給Shiro平臺執(zhí)行真正的認(rèn)證測試:

Subject currentUser = SecurityUtils.getSubject();
currentUser.login(token);

獲取到當(dāng)前正在訪問的用戶后,用其調(diào)用一次login(登錄)方法,將之前創(chuàng)建的AuthenticationToken實(shí)例作為登錄方法的參數(shù)傳過去.
每次login(登錄)方法的調(diào)用都意味著需要重新嘗試認(rèn)證一次.

6

第三步:處理成功和失敗

如果login(登錄)方法平穩(wěn)的執(zhí)行成功了,這就意味著認(rèn)證結(jié)束了!Subject(用戶)已經(jīng)被認(rèn)證了.此程序線程可以在沒有中斷的情況下繼續(xù)執(zhí)行,并且隨后任意次數(shù)的執(zhí)行SecurityUtils.getSubject()方法都將返回已經(jīng)授權(quán)的Subject用戶實(shí)例,同時隨后任意次數(shù)的執(zhí)行subject.isAuthenticated()方法都將返回true(真).

但是如果登錄失敗會怎么樣?比如,假如終端用戶提供了一個錯誤的密碼,或者訪問系統(tǒng)次數(shù)太多又或者他們的賬戶被鎖定?

Shiro有一個豐富的運(yùn)行時AuthenticationException(身份驗(yàn)證異常)層次結(jié)構(gòu),可以準(zhǔn)確指出嘗試失敗的原因.您可以將登錄封裝在try/catch塊中,捕捉任何希望的異常,并相應(yīng)地對它們作出處理.例如:

try {
    currentUser.login(token);
} catch ( UnknownAccountException uae ) {  // 未知賬戶異常
    ...
} catch ( IncorrectCredentialsException ice ) { // 密碼錯誤異常
    ...
} catch ( LockedAccountException lae ) {  // 賬戶被鎖定異常
    ...
} catch ( ExcessiveAttemptsException eae ) {  // 過度嘗試異常
    ...
} ... catch your own ... // 捕捉你自定義的異常
} catch ( AuthenticationException ae ) { 
    //沒有預(yù)料到的異常錯誤?
}
// 沒問題,向預(yù)期的那樣運(yùn)行...

如果所有已經(jīng)存在的異常類型都不滿足你的需要,你可以自定義新的AuthenticationException來表示特定的失敗場景.

登錄失敗提示小技巧

雖然代碼可以根據(jù)需要對特定異常作出反應(yīng)并執(zhí)行邏輯,但安全性最佳的方案是僅在發(fā)生故障時向最終用戶顯示一般故障消息,例如“用戶名或密碼不正確”.這確保沒有特定的信息可供黑客使用,黑客可能正在嘗試不同的攻擊方向.

7

remeberd(已記住)和authenticated(已授權(quán))

就像上面例子中展示的那樣,除了普通登錄外,Shiro還提供了"remember me"(記住我)的概念.現(xiàn)在有必要指出Shiro中remeberd Subject(已記住的用戶)和實(shí)際authenticated Subject(已認(rèn)證的用戶)的細(xì)微不同點(diǎn):

  • 已記住: 一個已記住的Subject(用戶)不是匿名用戶,而且此用戶有一個已知的身份(比如:subject.getPrincipals()方法返回的就非空).但是這個身份是基于上一次認(rèn)證留下的session.subject.isRemembered()方法返回true的時候就代表一個subject(用戶)被認(rèn)為是已記住的狀態(tài).
    -已授權(quán): 一個已授權(quán)的Subject(用戶)代表用戶在當(dāng)前session成功認(rèn)證的狀態(tài)(比如:login[登錄]方法在不拋出任何異常的情況下被調(diào)用).只要subject.isAuthenticated()方法返回true就可以認(rèn)定當(dāng)前用戶已認(rèn)證.
互斥性

已記住和已認(rèn)證這兩個狀態(tài)只能存在一個,不能同時存在.

8

為什么要有區(qū)分?

認(rèn)證這個詞有證明的含義.那就是說已經(jīng)得到保證此用戶已經(jīng)證明了他們是他們說的誰誰誰.

當(dāng)一個用戶只記住了之前的應(yīng)用信息,證明的過程早已成為歷史:已記住身份給出了系統(tǒng)一個當(dāng)前用戶可能是誰的提示,但事實(shí)上,沒有任何辦法保證已記住的用戶就是預(yù)期的用戶.一旦用戶已認(rèn)證,他們不屬于已記住的范圍,因?yàn)樗麄兊纳矸菀呀?jīng)在當(dāng)前session中得到確認(rèn).

因此盡管程序大部分情況下仍可以針對記住的身份執(zhí)行用戶特定的邏輯,比如說自定義的視圖,但不要執(zhí)行敏感的操作直到用戶成功執(zhí)行身份認(rèn)證使其身份得到確定.

例如,檢查一個Subject(用戶)是否可以訪問財(cái)務(wù)信息應(yīng)該取決于isAuthenticated()方法被認(rèn)證為真,而不是isRemembered()方法被記住為真,要確保該Subject(用戶)是期望用戶的同時還要確保用戶通過身份認(rèn)證.

9

一個例子說明

下面是一個非常常見的場景幫助說明被記住和被認(rèn)證之間差別為何重要。

假設(shè)你使用淘寶進(jìn)行網(wǎng)上購物,你已經(jīng)成功登錄并且在購物籃中添加了一些書籍,但由于你臨時要參加一個會議,匆忙中你忘記退出登錄,當(dāng)會議結(jié)束,回家的時間到了,于是你離開了辦公室.

第二天當(dāng)你回到工作,你意識到你沒有完成你的購買,于是你回到淘寶網(wǎng)站,這時淘寶網(wǎng)站記得你是誰,并通過你的名字向你打招呼,同時給你提供個性化的圖書推薦,對于淘寶網(wǎng)站,subject.isRemembered()方法將返回true.

但是當(dāng)你想訪問已買到的寶貝功能完成購買的時候會怎樣呢?雖然淘寶網(wǎng)站'記住'了你(isRemembered() == true),但它不能擔(dān)甭樱現(xiàn)在的你就是原來的你(也許是正在使用你計(jì)算機(jī)的同事).

于是在你執(zhí)行像查看用戶私人信息之類的敏感操作之前,淘寶網(wǎng)站會強(qiáng)制你再次登錄以使他們確信你的身份,在你登錄之后,你的身份已經(jīng)被驗(yàn)證,對于淘寶網(wǎng)站來說此時isAuthenticated()方法將返回true.

這類情景經(jīng)常發(fā)生,所以Shiro加入了該功能,你可以在你的程序中使用.現(xiàn)在是使用isRemembered()還是使用 isAuthenticated()來定制你的視圖和工作流完全取決于你自己,但Shiro將繼續(xù)維護(hù)這項(xiàng)功能以防你可能會需要.

10

退出登錄

與已認(rèn)證相對的是釋放所有已知的身份信息,當(dāng)Subject(用戶)與程序不再交互了,你可以調(diào)用subject.logout()方法刪除所有身份信息.

currentUser.logout(); // 刪除所有認(rèn)證信息,使session失效,通俗的說就是退出登錄

當(dāng)你調(diào)用logout,任何現(xiàn)存的session將變?yōu)椴豢捎貌⑶宜械纳矸菪畔G失(如:在web程序中,位于服務(wù)器的記住我的 Cookie信息將同樣被刪除).

當(dāng)一個Subject(用戶)退出登錄,Subject(用戶)被重新認(rèn)定為匿名的,對于web程序,如果需要可以重新login(登錄).

Web 程序需注意

因?yàn)樵?Web 程序中記住身份信息往往使用cookies,而 cookies 只能在 Response 提交時才能被刪除,所以強(qiáng)烈要求在為最終用戶調(diào)用subject.logout()之后立即將用戶引導(dǎo)到一個新頁面,確保任何與安全相關(guān)的Cookies如期刪除,這是HTTP本身cookies功能的限制而不是Shiro的限制.

11

認(rèn)證的順序

直到現(xiàn)在,我們只看到如何在程序代碼中驗(yàn)證一個Suject(用戶),現(xiàn)在我們看一下當(dāng)一個身份驗(yàn)證觸發(fā)時Shiro內(nèi)部發(fā)生了什么.
我們?nèi)允褂弥霸诩軜?gòu)章節(jié)里見到過的架構(gòu)圖,僅將左側(cè)跟認(rèn)證相關(guān)的組件高亮,每一個數(shù)字代表認(rèn)證中的一個步驟:

12

13

第1步:程序代碼調(diào)用Subject.login方法,向AuthenticationToken(認(rèn)證令牌)實(shí)例的構(gòu)造函數(shù)傳遞用戶的身份和證明信息.

第2步:Subject實(shí)例,通常是一個DelegatingSubject(或其子類)通過調(diào)用securityManager.login(token)將這個令牌轉(zhuǎn)交給程序的SecurityManager.

第3步:SecurityManager,類似于“傘”的安全管理組件,得到令牌后通過調(diào)用authenticator.authenticate(token)方法簡單地將其轉(zhuǎn)交給內(nèi)部的Authenticator認(rèn)證器實(shí)例.大部分情況下是一個ModularRealmAuthenticator實(shí)例,ModularRealmAuthenticator本質(zhì)上為Apache Shiro提供一個PAM(Pluggable_Authentication_Modules 可插拔認(rèn)證模塊)類型的范例.用來支持在驗(yàn)證過程中協(xié)調(diào)一個或多個Realm實(shí)例(在 PAM 術(shù)語中每一個Realm稱為一個“模塊”,每個realm代表一個獲取安全數(shù)據(jù)源的方式).

第4步:如程序配置了多個Realm模塊,ModularRealmAuthenticator實(shí)例將使用其配置的 AuthenticationStrategy(認(rèn)證策略)開始一個多Realm身份驗(yàn)證的嘗試.在Realm被驗(yàn)證調(diào)用的整個過程中,AuthenticationStrategy(認(rèn)證策略)被調(diào)用來回應(yīng)每個Realm的結(jié)果.我們將稍后討論 AuthenticationStrategies(認(rèn)證策略).

注意:單 Realm 程序
如果僅有一個 Realm 被配置,它直接被調(diào)用--在單 Realm 程序中不需要AuthenticationStrategy

第5步:每一個配置的 Realm 都被檢驗(yàn)看其是否支持提交的AuthenticationToken,如果支持,則該 Realm 的getAuthenticationInfo方法將隨著令牌的提交而被調(diào)用,getAuthenticationInfo方法有效地表示該特定Realm(安全領(lǐng)域)的單一身份驗(yàn)證嘗試,我們將稍后討論Realm驗(yàn)證行為.

14

認(rèn)證器

就像之前提到過的,Shiro的SecurityManager的實(shí)現(xiàn)類默認(rèn)使用一個ModularRealmAuthenticator(通用安全領(lǐng)域認(rèn)證器)實(shí)例, ModularRealmAuthenticator(通用安全領(lǐng)域認(rèn)證器)同樣支持單 Realm 和多 Realm

在一個單 Realm 程序中,ModularRealmAuthenticator(通用安全領(lǐng)域認(rèn)證器)將直接調(diào)用單獨(dú)的Realm,如果配置有兩個或以上 Realm,將會使用AuthenticationStrategy(認(rèn)證策略)實(shí)例來協(xié)調(diào)如何進(jìn)行驗(yàn)證,我們將在下面的章節(jié)中討論 AuthenticationStrategy.

如果你希望用自定義的Authenticator(認(rèn)證器)來配置SecurityManager,可以在shiro.ini中這樣自定義:

[main]
...
authenticator = com.foo.bar.CustomAuthenticator
securityManager.authenticator = $authenticator

盡管在實(shí)際操作中,ModularRealmAuthenticator(通用安全領(lǐng)域認(rèn)證器)已經(jīng)滿足常見需求.

15

認(rèn)證策略

當(dāng)一個程序中定義了兩個或多個 realm 時,ModularRealmAuthenticator(通用安全領(lǐng)域認(rèn)證器)使用一個內(nèi)部的AuthenticationStrategy(認(rèn)證策略)組件來決定一次認(rèn)證是否成功.

例如,如果一個 Realm 驗(yàn)證一個AuthenticationToken成功,但其他的都失敗了,那這次嘗試是否被認(rèn)為是成功的呢?是不是所有 Realm 驗(yàn)證都成功了才認(rèn)為是成功?又或者一個 Realm 驗(yàn)證成功后,是否還有必要討論其他Realm? AuthenticationStrategy(認(rèn)證策略)負(fù)責(zé)幫助解決這些問題.

認(rèn)證策略是一個無狀態(tài)的組件,在身份驗(yàn)證嘗試期間會被查詢4次(這4次交互所需的任何必要狀態(tài)都將作為方法參數(shù)給出):
1.在任何 Realms 被驗(yàn)證之前
2.在某個的 Realm 的 getAuthenticationInfo 方法調(diào)用之前
3.在某個的 Realm 的 getAuthenticationInfo 方法調(diào)用之后
4.在所有的 Realm 被驗(yàn)證之后

AuthenticationStrategy 還有責(zé)任從每一個成功的 Realm 中收集結(jié)果并將它們綁定到一個單獨(dú)的 AuthenticationInfo,這個AuthenticationInfo 實(shí)例是被 Authenticator 實(shí)例返回的,并且 Shiro 用它來展現(xiàn)一個 Subject(用戶)的最終身份(也就是 Principals).

Subject(用戶)身份view(展示)
如果你在程序中使用多于一個的 Realm 從多個數(shù)據(jù)源中獲取帳戶數(shù)據(jù),AuthenticationStrategy最終負(fù)責(zé)應(yīng)用程序所看到的 Subject 身份最終合并的視圖.

16

Shiro 有3個具體的AuthenticationStrategy實(shí)現(xiàn)類:

實(shí)現(xiàn)類 : 描述

  • AtLeastOneSuccessfulStrategy : 如果有一個或多個Realm驗(yàn)證成功,整體認(rèn)證被認(rèn)為是成功的,如果沒有一個驗(yàn)證成功,則該次認(rèn)證失敗
  • FirstSuccessfulStrategy : 只有從第一個成功驗(yàn)證的Realm返回的信息會被使用,以后的Realm將被忽略,如果沒有一個驗(yàn)證成功,則該次認(rèn)證失敗
  • AllSuccessfulStrategy : 所有配置的Realm在全部嘗試中都成功驗(yàn)證才被認(rèn)為是成功,如果有一個驗(yàn)證不成功,則該次認(rèn)證失敗

ModularRealmAuthenticator默認(rèn)使用AtLeastOneSuccessfulStrategy實(shí)現(xiàn),這也是最常用的策略,然而你也可以配置成你希望的其他策略:

[main]
...
authcStrategy = org.apache.shiro.authc.pam.FirstSuccessfulStrategy
securityManager.authenticator.authenticationStrategy = $authcStrategy
...
17

自定義的認(rèn)證策略
如果你希望創(chuàng)建你自己的AuthenticationStrategy實(shí)現(xiàn),你可以使用 org.apache.shiro.authc.pam.AbstractAuthenticationStrategy作為起點(diǎn).AbstractAuthenticationStrategy類自動實(shí)現(xiàn)綁定/聚集行為同時將來自于每一個 Realm 的結(jié)果收集到一個 AuthenticationInfo 實(shí)例中.

18

Realm 驗(yàn)證的順序

非常重要的一點(diǎn)是,和 Realm 交互的ModularRealmAuthenticator按迭代(iteration)順序執(zhí)行

ModularRealmAuthenticator可以訪問為SecurityManager配置的Realm實(shí)例,當(dāng)嘗試一次認(rèn)證時,它將在集合中遍歷,支持對提交的AuthenticationToken進(jìn)行處理的每個Realm都將執(zhí)行 Realm 的 getAuthenticationInfo方法

隱含的順序

在使用 Shiro INI 配置文件時,你可以通過配置 Realm 來使程序按你希望的順序去處理 AuthenticationToken,例如,在shiro.ini 中,Realm 將按照他們在 INI 文件中定義的順序執(zhí)行:

blahRealm = com.company.blah.Realm
...
fooRealm = com.company.foo.Realm
...
barRealm = com.company.another.Realm
19

SecurityManager上配置了這三個 Realm,但沒有設(shè)置securityManager.realms屬性,此時在一個驗(yàn)證過程中blahRealm, fooRealm, 和 barRealm 將被按照他們定義的先后順序執(zhí)行.
加不加下面的配置順序都一樣:

securityManager.realms = $blahRealm, $fooRealm, $barRealm

20

使用這種配置方式,你不需要調(diào)用方法來設(shè)置 securityManager 的 realms 屬性,在程序讀取INI文件時每一個被定義的realm 將自動分配到 realms 屬性中

指定的順序

如果你希望明確定義 realm 執(zhí)行的順序,不管他們?nèi)绾伪欢x,你可以設(shè)置 SecurityManager 的 realms 屬性,例如,使用上面定義的 realm ,但你希望 blahRealm 最后執(zhí)行而不是第一個:

blahRealm = com.company.blah.Realm
...
fooRealm = com.company.foo.Realm
...
barRealm = com.company.another.Realm
securityManager.realms = $fooRealm, $barRealm, $blahRealm
...
21
明確包含Realm

當(dāng)你明確的配置 securityManager.realms 屬性時, 只有 被引用的 realm 將為 SecurityManager 配置,也就是說你可能在 INI 中定義了5個 realm , 但實(shí)際上只使用了3個, 如果在 realms 屬性中只引用了3個, 這和隱含的 realm 順序不同, 在那種情況下, 所有有效的 realm 都會用到.

Realm認(rèn)證

本章闡述了當(dāng)嘗試一次認(rèn)證時 Shiro 主要的工作流程,而在驗(yàn)證過程中,用到的 Realm 內(nèi)產(chǎn)生的工作流程(如上面提到的第5步)將在 Realm 章中 Realm Authentication 節(jié)討論

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末说榆,一起剝皮案震驚了整個濱河市虚吟,隨后出現(xiàn)的幾起案子寸认,更是在濱河造成了極大的恐慌,老刑警劉巖串慰,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件偏塞,死亡現(xiàn)場離奇詭異,居然都是意外死亡邦鲫,警方通過查閱死者的電腦和手機(jī)灸叼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來庆捺,“玉大人古今,你說我怎么就攤上這事√弦裕” “怎么了捉腥?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長醉者。 經(jīng)常有香客問我但狭,道長,這世上最難降的妖魔是什么撬即? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任立磁,我火速辦了婚禮,結(jié)果婚禮上剥槐,老公的妹妹穿的比我還像新娘唱歧。我一直安慰自己,他們只是感情好粒竖,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布颅崩。 她就那樣靜靜地躺著,像睡著了一般蕊苗。 火紅的嫁衣襯著肌膚如雪沿后。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天朽砰,我揣著相機(jī)與錄音尖滚,去河邊找鬼。 笑死瞧柔,一個胖子當(dāng)著我的面吹牛漆弄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播造锅,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼撼唾,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了哥蔚?” 一聲冷哼從身側(cè)響起倒谷,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤蛛蒙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后恨锚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宇驾,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年猴伶,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塌西。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡他挎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出捡需,到底是詐尸還是另有隱情办桨,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布站辉,位于F島的核電站呢撞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏饰剥。R本人自食惡果不足惜殊霞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望汰蓉。 院中可真熱鬧绷蹲,春花似錦、人聲如沸顾孽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽若厚。三九已至拦英,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間测秸,已是汗流浹背疤估。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留乞封,地道東北人做裙。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像肃晚,于是被迫代替她去往敵國和親锚贱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容