Spring Security 詳解

Spring Security 是一個(gè)基于 Spring AOP 和 Servlet 過濾器的安全框架嗜闻,它提供了安全性方面的解決方案,同時(shí)在Web請求和方法級處理身份確認(rèn)和授權(quán)

Spring Boot 添加 Spring Security

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Spring Security 模塊

  • 核心模塊 - spring-security-core.jar:包含核心驗(yàn)證和訪問控制類和接口桅锄,遠(yuǎn)程支持的基本配置API琉雳,是基本模塊
  • 遠(yuǎn)程調(diào)用 - spring-security-remoting.jar:提供與 Spring Remoting 集成
  • 網(wǎng)頁 - spring-security-web.jar:包括網(wǎng)站安全的模塊,提供網(wǎng)站認(rèn)證服務(wù)和基于URL訪問控制
  • 配置 - spring-security-config.jar:包含安全命令空間解析代碼友瘤,若使用XML進(jìn)行配置則需要
  • LDAP - spring-security-ldap.jar:LDAP 驗(yàn)證和配置翠肘,若需要LDAP驗(yàn)證和管理LDAP用戶實(shí)體
  • ACL訪問控制表 - spring-security-acl.jar:ACL專門領(lǐng)域?qū)ο蟮膶?shí)現(xiàn)
  • CAS - spring-security-cas.jar:CAS客戶端繼承,若想用CAS的SSO服務(wù)器網(wǎng)頁驗(yàn)證
  • OpenID - spring-security-openid.jar:OpenID網(wǎng)頁驗(yàn)證支持
  • Test - spring-security-test.jar:支持Spring Security的測試

認(rèn)證流程

  1. 用戶使用用戶名和密碼登錄
  2. 用戶名密碼被過濾器(默認(rèn)為 UsernamePasswordAuthenticationFilter)獲取到辫秧,封裝成 Authentication
  3. token(Authentication實(shí)現(xiàn)類)傳遞給 AuthenticationManager 進(jìn)行認(rèn)證
  4. AuthenticationManager 認(rèn)證成功后返回一個(gè)封裝了用戶權(quán)限信息的 Authentication 對象
  5. 通過調(diào)用 SecurityContextHolder.getContext().setAuthentication(...) 將 Authentication 對象賦給當(dāng)前的 SecurityContext

    默認(rèn)執(zhí)行順序:

    UsernamePasswordAuthenticationFilter :

    1. 用戶通過url:/login 登錄束倍,該過濾器接收表單用戶名密碼
    2. 判斷用戶名密碼是否為空
    3. 生成 UsernamePasswordAuthenticationToken
    4. 將 Authentiction 傳給 AuthenticationManager接口的 authenticate 方法進(jìn)行認(rèn)證處理
    5. AuthenticationManager 默認(rèn)是實(shí)現(xiàn)類為 ProviderManager ,ProviderManager 委托給 AuthenticationProvider 進(jìn)行處理
    6. UsernamePasswordAuthenticationFilter 繼承了 AbstractAuthenticationProcessingFilter 抽象類盟戏,AbstractAuthenticationProcessingFilter 在 successfulAuthentication 方法中對登錄成功進(jìn)行了處理绪妹,通過 SecurityContextHolder.getContext().setAuthentication() 方法將 Authentication 認(rèn)證信息對象綁定到 SecurityContext
    7. 下次請求時(shí),在過濾器鏈頭的 SecurityContextPersistenceFilter 會(huì)從 Session 中取出用戶信息并生成 Authentication(默認(rèn)為 UsernamePasswordAuthenticationToken),并通過 SecurityContextHolder.getContext().setAuthentication() 方法將 Authentication 認(rèn)證信息對象綁定到 SecurityContext
    8. 需要權(quán)限才能訪問的請求會(huì)從 SecurityContext 中獲取用戶的權(quán)限進(jìn)行驗(yàn)證

    DaoAuthenticationProvider (實(shí)現(xiàn)了 AuthenticationProvider):

    1. 通過 UserDetailsService 獲取 UserDetails
    2. 將 UserDetails 和 UsernamePasswordAuthentionToken 進(jìn)行認(rèn)證匹配用戶名密碼是否正確
    3. 若正確則通過 UserDetails 中用戶的權(quán)限津坑、用戶名等信息生成一個(gè)新的 Authentication 認(rèn)證對象并返回

相關(guān)類

WebSecurityConfigurerAdapter

  • 為創(chuàng)建 WebSecurityConfigurer 實(shí)例提供方便的基類累舷,重寫它的 configure 方法來設(shè)置安全細(xì)節(jié)
    • configure(HttpSecurity http):重寫該方法,通過 http 對象的 authorizeRequests()方法定義URL訪問權(quán)限廊移,默認(rèn)會(huì)為 formLogin() 提供一個(gè)簡單的測試HTML頁面
    • _configureGlobal(AuthenticationManagerBuilder auth) _:通過 auth 對象的方法添加身份驗(yàn)證

SecurityContextHolder

  • SecurityContextHolder 用于存儲(chǔ)安全上下文信息(如操作用戶是誰、用戶是否被認(rèn)證探入、用戶權(quán)限有哪些)狡孔,它用 ThreadLocal 來保存 SecurityContext,者意味著 Spring Security 在用戶登錄時(shí)自動(dòng)綁定到當(dāng)前現(xiàn)場蜂嗽,用戶退出時(shí)苗膝,自動(dòng)清除當(dāng)前線程認(rèn)證信息,SecurityContext 中含有正在訪問系統(tǒng)用戶的詳細(xì)信息

AuthenticationManagerBuilder

  • 用于構(gòu)建認(rèn)證 AuthenticationManager 認(rèn)證植旧,允許快速構(gòu)建內(nèi)存認(rèn)證辱揭、LDAP身份認(rèn)證、JDBC身份驗(yàn)證病附,添加 userDetailsService(獲取認(rèn)證信息數(shù)據(jù)) 和 AuthenticationProvider's(定義認(rèn)證方式)
  • 內(nèi)存驗(yàn)證:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      auth.inMemoryAuthentication()
            .withUser("user").password("123").roles("USER").and()
            .withUser("admin").password("456").roles("USER","ADMIN");
}
  • JDBC 驗(yàn)證:
@Autowired
private DataSource dataSource;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.jdbcAuthentication()
            .dataSource(dataSource)
            .withDefaultSchema()
            .withUser("linyuan").password("123").roles("USER").and()
            .withUser("linyuan2").password("456").roles("ADMIN");
}
  • userDetailsService(T userDetailsService):傳入自定義的 UserDetailsService 獲取認(rèn)證信息數(shù)據(jù)
  • authenticationProvider(AuthenticationProvider authenticationProvider) :傳入自定義認(rèn)證過程

UserDetailsService

  • 該接口僅有一個(gè)方法 loadUserByUsername问窃,Spring Security 通過該方法獲取

UserDetails

  • 我們可以實(shí)現(xiàn)該接口來定義自己認(rèn)證用戶的獲取方式(如數(shù)據(jù)庫中獲取)完沪,認(rèn)證成功后會(huì)將 UserDetails 賦給 Authentication 的 principal 屬性域庇,然后再把 Authentication 保存到 SecurityContext 中嵌戈,之后需要實(shí)用用戶信息時(shí)通過 SecurityContextHolder 獲取存放在 SecurityContext 中的 Authentication 的 principal

Authentication

  • Authentication 是一個(gè)接口,用來表示用戶認(rèn)證信息听皿,在用戶登錄認(rèn)證之前相關(guān)信息(用戶傳過來的用戶名密碼)會(huì)封裝為一個(gè) Authentication 具體實(shí)現(xiàn)類對象熟呛,默認(rèn)情況下為 UsernamePasswordAuthenticationToken,登錄之后(通過AuthenticationManager認(rèn)證)會(huì)生成一個(gè)更詳細(xì)的尉姨、包含權(quán)限的對象庵朝,然后把它保存在權(quán)限線程本地的 SecurityContext 中,供后續(xù)權(quán)限鑒定用

GrantedAuthority

  • GrantedAuthority 是一個(gè)接口又厉,它定義了一個(gè) getAuthorities() 方法返回當(dāng)前 Authentication 對象的擁有權(quán)限字符串九府,用戶有權(quán)限是一個(gè) GrantedAuthority 數(shù)組,每一個(gè) GrantedAuthority 對象代表一種用戶
  • 通常搭配 SimpleGrantedAuthority 類使用

AuthenticationManager

  • AuthenticationManager 是用來處理認(rèn)證請求的接口覆致,它只有一個(gè)方法 authenticate()昔逗,該方法接收一個(gè) Authentication 作為對象,如果認(rèn)證成功則返回一個(gè)封裝了當(dāng)前用戶權(quán)限信息的 Authentication 對象進(jìn)行返回
  • 它默認(rèn)的實(shí)現(xiàn)是 ProviderManager篷朵,但它不處理認(rèn)證請求勾怒,而是將委托給 AuthenticationProvider 列表,然后依次使用 AuthenticationProvider 進(jìn)行認(rèn)證声旺,如果有一個(gè) AuthenticationProvider 認(rèn)證的結(jié)果不為null笔链,則表示成功(否則失敗,拋出 ProviderNotFoundException)腮猖,之后不在進(jìn)行其它 AuthenticationProvider 認(rèn)證鉴扫,并作為結(jié)果保存在 ProviderManager
  • 認(rèn)證校驗(yàn)時(shí)最常用的方式就是通過用戶名加載 UserDetails,然后比較 UserDetails 密碼與請求認(rèn)證是否一致澈缺,一致則通過坪创,Security 內(nèi)部的 DaoAuthenticationProvider 就是實(shí)用這種方式
  • 認(rèn)證成功后加載 UserDetails 來封裝要返回的 Authentication 對象,加載的 UserDetails 對象是包含用戶權(quán)限等信息的姐赡。認(rèn)證成功返回的 Authentication 對象將會(huì)保存在當(dāng)前的 SecurityContext 中

AuthenticationProvide

  • AuthenticationProvider 是一個(gè)身份認(rèn)證接口莱预,實(shí)現(xiàn)該接口來定制自己的認(rèn)證方式,可通過 UserDetailsSevice 對獲取數(shù)據(jù)庫中的數(shù)據(jù)
  • 該接口中有兩個(gè)需要實(shí)現(xiàn)的方法:
    • Authentication authenticate(Authentication authentication):認(rèn)證處理项滑,返回一個(gè) Authentication 的實(shí)現(xiàn)類則代表成功依沮,返回 null 則為認(rèn)證失敗
    • supports(Class<?> aClass):如果該 AuthenticationProvider 支持傳入的 Authentication 認(rèn)證對象,則返回 true 枪狂,如:return aClass.equals(UsernamePasswordAuthenticationToken.class);

AuthorityUtils

  • 是一個(gè)工具包危喉,用于操作 GrantedAuthority 集合的實(shí)用方法:
    • commaSeparatedStringToAuthorityList(String authorityString):從逗號分隔符中創(chuàng)建 GrantedAuthority 對象數(shù)組

AbstractAuthenticationProcessingFilter

  • 該抽象類繼承了 GenericFilterBean,是處理 form 登錄的過濾器州疾,與 form 登錄相關(guān)的所有操作都在該抽象類的子類中進(jìn)行(UsernamePasswordAuthenticationFilter 為其子類)辜限,比如獲取表單中的用戶名、密碼严蓖,然后進(jìn)行認(rèn)證等操作
  • 該類在 doFilter 方法中通過 attemptAuthentication() 方法進(jìn)行用戶信息邏輯認(rèn)證薄嫡,認(rèn)證成功會(huì)將用戶信息設(shè)置到 Session 中

UserDetails

  • 代表了Spring Security的用戶實(shí)體類氧急,帶有用戶名、密碼岂座、權(quán)限特性等性質(zhì),可以自己實(shí)現(xiàn)該接口杭措,供 Spring Security 安全認(rèn)證使用费什,Spring Security 默認(rèn)使用的是內(nèi)置的 User 類
  • 將從數(shù)據(jù)庫獲取的 User 對象傳入實(shí)現(xiàn)該接口的類,并獲取 User 對象的值來讓類實(shí)現(xiàn)該接口的方法
  • 通過 Authentication.getPrincipal() 的返回類型是 Object手素,但很多情況下其返回的其實(shí)是一個(gè) UserDetails 的實(shí)例

HttpSecurity

  • 用于配置全局 Http 請求的權(quán)限控制規(guī)則鸳址,對哪些請求進(jìn)行驗(yàn)證、不驗(yàn)證等
  • 常用方法:
    • authorizeRequests():返回一個(gè)配置對象用于配置請求的訪問限制
    • formLogin():返回表單配置對象泉懦,當(dāng)什么都不指定時(shí)會(huì)提供一個(gè)默認(rèn)的稿黍,如配置登錄請求,還有登錄成功頁面
    • logout():返回登出配置對象崩哩,可通過logoutUrl設(shè)置退出url
    • antMatchers:匹配請求路徑或請求動(dòng)作類型巡球,如:.antMatchers("/admin/**")
    • addFilterBefore: 在某過濾器之前添加 filter
    • addFilterAfter:在某過濾器之后添加 filter
    • addFilterAt:在某過濾器相同位置添加 filter,不會(huì)覆蓋相同位置的 filter
    • hasRole:結(jié)合 antMatchers 一起使用邓嘹,設(shè)置請求允許訪問的角色權(quán)限或IP酣栈,如:
    .antMatchers("/admin/**").hasAnyRole("ROLE_ADMIN","ROLE_USER") 
    
    方法名 用途
    access(String) SpringEL表達(dá)式結(jié)果為true時(shí)可訪問
    anonymous() 匿名可訪問
    denyAll() 用戶不可以訪問
    fullyAuthenticated() 用戶完全認(rèn)證訪問(非remember me下自動(dòng)登錄)
    hasAnyAuthority(String…) 參數(shù)中任意權(quán)限可訪問
    hasAnyRole(String…) 參數(shù)中任意角色可訪問
    hasAuthority(String) 某一權(quán)限的用戶可訪問
    hasRole(String) 某一角色的用戶可訪問
    permitAll() 所有用戶可訪問
    rememberMe() 允許通過remember me登錄的用戶訪問
    authenticated() 用戶登錄后可訪問
    hasIpAddress(String) 用戶來自參數(shù)中的IP可訪問

注解與Spring EL

  • @EnableWebSecurity:開啟 Spring Security 注解
  • @EnableGlobalMethodSecurity(prePostEnabled=true):開啟security方法注解
  • @PreAuthorize:在方法調(diào)用前,通過SpringEL表達(dá)式限制方法訪問
@PreAuthorize("hasRole('ROLE_ADMIN')")
public void addUser(User user){
    //如果具有權(quán)限 ROLE_ADMIN 訪問該方法
    ....
}
  • @PostAuthorize:允許方法調(diào)用汹押,但時(shí)如果表達(dá)式結(jié)果為false拋出異常
//returnObject可以獲取返回對象user矿筝,判斷user屬性username是否和訪問該方法的用戶對象的用戶名一樣。不一樣則拋出異常棚贾。
@PostAuthorize("returnObject.user.username==principal.username")
public User getUser(int userId){
   //允許進(jìn)入
...
    return user;    
}
  • @PostFilter:允許方法調(diào)用窖维,但必須按表達(dá)式過濾方法結(jié)果
//將結(jié)果過濾,即選出性別為男的用戶
@PostFilter("returnObject.user.sex=='男' ")
public List<User> getUserList(){
    //允許進(jìn)入
    ...
    return user;    
}
  • @PreFilter:允許方法調(diào)用妙痹,但必須在進(jìn)入方法前過濾輸入值

Spring EL 表達(dá)式:

表達(dá)式 描述
hasRole ([role]) 當(dāng)前用戶是否擁有指定角色
hasAnyRole([role1,role2]) 多個(gè)角色是一個(gè)以逗號進(jìn)行分隔的字符串铸史。如果當(dāng)前用戶擁有指定角色中的任意一個(gè)則返回true
hasAuthority ([auth]) 等同于hasRole
hasAnyAuthority([auth1,auth2]) 等同于 hasAnyRole
Principle 代表當(dāng)前用戶的 principle對象
authentication 直接從 Security context獲取的當(dāng)前 Authentication對象
permitAll 總是返回true,表示允許所有的訪問
denyAll 總是返回false,表示拒絕所有的訪問訪問
isAnonymous() 當(dāng)前用戶是否是一個(gè)匿名用戶
isRememberMe 表示當(dāng)前用戶是否是通過remember - me自動(dòng)登錄的
isAuthenticated() 表示當(dāng)前用戶是否已經(jīng)登錄認(rèn)證成功了
isFullAuthenticated() 如果當(dāng)前用戶既不是一個(gè)匿名用戶,同時(shí)又不是通過Remember-Me自動(dòng)登錄的,則返回true

密碼加密(PassWordEncoder)

  • Spring 提供的一個(gè)用于對密碼加密的接口,首選實(shí)現(xiàn)類為 BCryptPasswordEncoder
  • 通過@Bean注解將它注入到IOC容器:
@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

過濾器鏈

SecurityContextPersistenceFilter

  • 過濾器鏈頭怯伊,是從 SecurityContextRepository 中取出用戶認(rèn)證信息沛贪,默認(rèn)實(shí)現(xiàn)為 HttpSessionSecurityContextRepository,它會(huì)從 Session 中取出已認(rèn)證的用戶信息震贵,提高效率利赋,避免每次請求都要查詢用戶認(rèn)證信息
  • 取出之后會(huì)放入 SecurityContextHolder 中,以便其它 filter 使用猩系,SecurityContextHolder 使用 ThreadLocal 存儲(chǔ)用戶認(rèn)證信息媚送,保證線程之間信息隔離,最后再 finally 中清除該信息

WebAsyncManagerIntegrationFilter

  • 提供了對 SecurityContext 和 WebAsyncManager 的集成寇甸,會(huì)把 SecurityContext 設(shè)置到異步線程塘偎,使其也能獲取到用戶上下文認(rèn)證信息

HanderWriterFilter

  • 會(huì)往請求的 Header 中添加相應(yīng)的信息

CsrfFilter

  • 跨域請求偽造過濾器疗涉,通過客戶端穿來的 token 與服務(wù)端存儲(chǔ)的 token 進(jìn)行對比來判斷請求

LogoutFilter

  • 匹配URL,默認(rèn)為 /logout吟秩,匹配成功后則會(huì)用戶退出咱扣,清除認(rèn)證信息,若有自己的退出邏輯涵防,該過濾器可以關(guān)閉

UsernamePasswordAuthenticationFilter

  • 登錄認(rèn)證過濾器闹伪,默認(rèn)是對 /login 的 POST 請求進(jìn)行認(rèn)證,首先該方法會(huì)調(diào)用 attemptAuthentication 嘗試認(rèn)證獲取一個(gè) Authentication 認(rèn)證對象壮池,然后通過 sessionStrategy.onAuthentication 執(zhí)行持久化偏瓤,也就是保存認(rèn)證信息,然后轉(zhuǎn)向下一個(gè) Filter椰憋,最后調(diào)用 successfulAuthentication 執(zhí)行認(rèn)證后事件
  • attemptAuthentication 該方法是認(rèn)證的主要方法厅克,認(rèn)證基本流程為 UserDeatilService 根據(jù)用戶名獲取到用戶信息,然后通過 UserDetailsChecker.check 對用戶狀態(tài)進(jìn)行校驗(yàn)橙依,最后通過 additionalAuthenticationChecks 方法對用戶密碼進(jìn)行校驗(yàn)完后認(rèn)證后证舟,返回一個(gè)認(rèn)證對象

DefaultLoginPageGeneratingFilter

  • 當(dāng)請求為登錄請求時(shí),生成簡單的登錄頁面窗骑,可以關(guān)閉

BasicAuthenticationFilter

  • Http Basci 認(rèn)證的支持褪储,該認(rèn)證會(huì)把用戶名密碼使用 base64 編碼后放入 header 中傳輸,認(rèn)證成功后會(huì)把用戶信息放入 SecurityContextHolder 中

RequestCacheAwareFilter

  • 恢復(fù)被打斷時(shí)的請求

SecurityContextHolderAwareRequestFilter

  • 針對 Servlet api 不同版本做一些包裝

AnonymousAuthenticationFIlter

  • SecurityContextHolder 中認(rèn)證信息為空慧域,則會(huì)創(chuàng)建一個(gè)匿名用戶到 SecurityContextHolder 中

SessionManagementFilter

  • 與登錄認(rèn)證攔截時(shí)作用一樣鲤竹,持久化用戶登錄信息,可以保存到 Session 中昔榴,也可以保存到 cookie 或 redis 中

ExceptionTranslationFilter

  • 異常攔截辛藻,處于 Filter 鏈條后部,只能攔截其后面的節(jié)點(diǎn)并著重處理 AuthenticationException 與 AccessDeniedException 異常
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末互订,一起剝皮案震驚了整個(gè)濱河市吱肌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌仰禽,老刑警劉巖氮墨,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異吐葵,居然都是意外死亡规揪,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門温峭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來猛铅,“玉大人,你說我怎么就攤上這事凤藏〖楹觯” “怎么了堕伪?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長栗菜。 經(jīng)常有香客問我欠雌,道長,這世上最難降的妖魔是什么疙筹? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任富俄,我火速辦了婚禮,結(jié)果婚禮上腌歉,老公的妹妹穿的比我還像新娘蛙酪。我一直安慰自己齐苛,他們只是感情好翘盖,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著凹蜂,像睡著了一般馍驯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上玛痊,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天汰瘫,我揣著相機(jī)與錄音,去河邊找鬼擂煞。 笑死混弥,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的对省。 我是一名探鬼主播蝗拿,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蒿涎!你這毒婦竟也來了哀托?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤劳秋,失蹤者是張志新(化名)和其女友劉穎仓手,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體玻淑,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嗽冒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了补履。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辛慰。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖干像,靈堂內(nèi)的尸體忽然破棺而出帅腌,到底是詐尸還是另有隱情驰弄,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布速客,位于F島的核電站戚篙,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏溺职。R本人自食惡果不足惜岔擂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望浪耘。 院中可真熱鬧乱灵,春花似錦、人聲如沸七冲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽澜躺。三九已至蝉稳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間掘鄙,已是汗流浹背耘戚。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留操漠,地道東北人收津。 一個(gè)月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像浊伙,于是被迫代替她去往敵國和親撞秋。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

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