国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

擴展JAAS實現類實例級授權

2019-11-18 15:00:19
字體:
來源:轉載
供稿:網友

  構建更動態、更靈活并且伸縮性更好的企業應用程序
Carlos A. Fonseca(cafonseca@us.ibm.com)
軟件工程師,IBM

java 認證和授權服務”(Java Authentication and Authorization Service,JAAS)是對 Java 2 SDK 的擴展。在 JAAS 下,可以給予用戶或服務特定的許可權來執行 Java 類中的代碼。在本文中,軟件工程師 Carlos Fonseca 向您展示如何為企業擴展 JAAS 框架。向 JAAS 框架添加類實例級授權和特定關系使您能夠構建更動態、更靈活并且伸縮性更好的企業應用程序。請單擊文章頂部或底部的討論,在討論論壇與作者和其他讀者分享您對本文的想法。
大多數 Java 應用程序都需要某種類實例級的訪問控制。例如,基于 Web 的、自我服務的拍賣應用程序的規范可能有下列要求:


任何已注冊(經過認證)的用戶都可以創建一個拍賣,但只有創建拍賣的用戶才可以修改這個拍賣。

這意味著任何用戶都可以執行被編寫用來創建 AUCtion 類實例的代碼,但只有擁有該實例的用戶可以執行用來修改它的代碼。通常情況下,創建 Auction 實例的用戶就是所有者。這被稱為類實例所有者關系(class instance owner relationship)。

該應用程序的另一個要求可能是:


任何用戶都可以為拍賣創建一個投標,拍賣的所有者可以接受或拒絕任何投標。

再一次,任何用戶都可以執行被編寫用來創建 Bid 類實例的代碼,但只有擁有該實例的用戶會被授予修改該實例的許可權。而且,Auction 類實例的所有者必須能夠修改相關的 Bid 類實例中的接受標志。這意味著在 Auction 實例和相應的 Bid 實例之間有一種被稱為特定關系(special relationship)的關系。

不幸的是,“Java 認證和授權服務”(JAAS)? 它是 Java 2 平臺的一部分 ? 沒有考慮到類實例級訪問控制或者特定關系。在本文中,我們將擴展 JAAS 框架使其同時包含這兩者。推動這種擴展的動力是答應我們將訪問控制分離到一個通用的框架,該框架使用基于所有權和特定關系的策略。然后治理員可以在應用程序的生命周期內更改這些策略。

在深入到擴展 JAAS 框架之前,我們將重溫一下 Java 2 平臺的訪問控制機制。我們將討論策略文件和許可權的使用,并討論 SecurityManager 和 accessController 之間的關系。

Java 2 平臺中的訪問控制
在 Java 2 平臺中,所有的代碼,不管它是本地代碼還是遠程代碼,都可以由策略來控制。策略(policy)由不同位置上的代碼的一組許可權定義,或者由不同的簽發者定義、或者由這兩者定義。許可權答應對資源進行訪問;它通過名稱來定義,并且可能與某些操作關聯在一起。

抽象類 java.security.Policy 被用于表示應用程序的安全性策略。缺省的實現由 sun.security.PRovider.PolicyFile 提供,在 sun.security.provider.PolicyFile 中,策略被定義在一個文件中。清單 1 是一個典型策略文件示例:

清單 1. 一個典型的策略文件
// Grant these permissions to code loaded from a sample.jar file
// in the C drive and if it is signed by XYZ
grant codebase "file:/C:/sample.jar", signedby "XYZ" {
// Allow socket actions to any host using port 8080
permission java.net.SocketPermission "*:8080", "accept, connect,
listen, resolve";
// Allows file access (read, write, execute, delete) in
// the user′s home Directory.
Permission java.io.FilePermission "${user.home}/-", "read, write,
execute, delete";
};



SecurityManager 對 AccessController
在標準 JDK 分發版中,控制代碼源訪問的機制缺省情況下是關閉的。在 Java 2 平臺以前,對代碼源的訪問都是由 SecurityManager 類治理的。SecurityManager 是由 java.security.manager 系統屬性啟動的,如下所示:


java -Djava.security.manager



在 Java 2 平臺中,可以將一個應用程序設置為使用 java.lang.SecurityManager 類或者 java.security.AccessController 類治理敏感的操作。AccessController 在 Java 2 平臺中是新出現的。為便于向后兼容,SecurityManager 類仍然存在,但把自己的決定提交 AccessController 類裁決。SecurityManager 和 AccessController 都使用應用程序的策略文件確定是否答應一個被請求的操作。清單 2 顯示了 AccessController 如何處理 SocketPermission 請求:

清單 2. 保護敏感操作

Public void someMethod() {
Permission permission =
new java.net.SocketPermission("localhost:8080", "connect");
AccessController.checkPermission(permission);
// Sensitive code starts here
Socket s = new Socket("localhost", 8080);
}



在這個示例中,我們看到 AccessController 檢查應用程序的當前策略實現。假如策略文件中定義的任何許可權暗示了被請求的許可權,該方法將只簡單地返回;否則拋出一個 AccessControlException 異常。在這個示例中,檢查實際上是多余的,因為缺省套接字實現的構造函數也執行相同的檢查。

在下一部分,我們將更仔細地看一下 AccessController 如何與 java.security.Policy 實現共同合作安全地處理應用程序請求。

運行中的 AccessController
AccessController 類典型的 checkPermission(Permission p) 方法調用可能會導致下面的一系列操作:

AccessController 調用 java.security.Policy 類實現的 getPermissions(CodeSource codeSource) 方法。


getPermissions(CodeSource codeSource) 方法返回一個 PermissionCollection 類實例,這個類實例代表一個相同類型許可權的集合。


AccessController 調用 PermissionCollection 類的 implies(Permission p) 方法。


接下來,PermissionCollection 調用集合中包含的單個 Permission 對象的 implies(Permission p) 方法。假如集合中的當前許可權對象暗示指定的許可權,則這些方法返回 true,否則返回 false。


現在,讓我們更具體地看一下這個訪問控制序列中的重要元素。

PermissionCollection 類
大多數許可權類類型都有一個相應的 PermissionCollection 類。這樣一個集合的實例可以通過調用 Permission 子類實現定義的 newPermissionCollection() 方法來創建。java.security.Policy 類實現的 getPermissions() 方法也可以返回 Permissions 類實例 ? PermissionCollection 的一個子類。這個類代表由 PermissionCollection 組織的不同類型許可權對象的一個集合。Permissions 類的 implies(Permission p) 方法可以調用單個 PermissionCollection 類的 implies(Permission p) 方法。

CodeSource 和 ProtectionDomain 類
許可權組合與 CodeSource(被用于驗證簽碼(signed code)的代碼位置和證書)被封裝在 ProtectionDomain 類中。有相同許可權和相同 CodeSource 的類實例被放在相同的域中。帶有相同許可權,但不同 CodeSource 的類被放在不同的域中。一個類只可屬于一個 ProtectionDomain。要為對象獲取 ProtectionDomain,請使用 java.lang.Class 類中定義的 getProtectionDomain() 方法。

許可權
賦予 CodeSource 許可權并不一定意味著答應所暗示的操作。要使操作成功完成,調用棧中的每個類必須有必需的許可權。換句話說,假如您將 java.io.FilePermission 賦給類 B,而類 B 是由類 A 來調用,那么類 A 必須也有相同的許可權或者暗示 java.io.FilePermission 的許可權。

在另一方面,調用類可能需要臨時許可權來完成另一個擁有那些許可權的類中的操作。例如,當從另一個位置加載的類訪問本地文件系統時,我們可能不信任它。但是,本地加載的類被授予對某個目錄的讀許可權。這些類可以實現 PrivilegedAction 接口來給予調用類許可權以便完成指定的操作。調用棧的檢查在碰到 PrivilegedAction 實例時停止,有效地將執行指定操作所必需的許可權授予所有的后繼類調用。

使用 JAAS
顧名思義,JAAS 由兩個主要組件組成:認證和授權。我們主要關注擴展 JAAS 的授權組件,但開始我們先簡要概述一下 JAAS 認證,緊接著看一下一個簡單的 JAAS 授權操作。

JAAS 中的用戶認證
JAAS 通過添加基于 subject 的策略加強了 Java 2 中定義的訪問控制安全性模型。許可權的授予不僅基于 CodeSource,還基于執行代碼的用戶。顯然,要使這個模型生效,每個用戶都必須經過認證。

JAAS 的認證機制建立在一組可插登錄模塊的基礎上。JAAS 分發版包含幾個 LoginModule 實現。LoginModules 可以用于提示用戶輸入用戶標識和密碼。LoginContext 類使用一個配置文件來確定使用哪個 LoginModule 對用戶進行認證。這個配置可以通過系統屬性 java.security.auth.login.config 指定。一個示例配置是:
java -Djava.security.auth.login.config=login.conf




下面是一個登錄配置文件的樣子:


Example {
com.ibm.resource.security.auth.LoginModuleExample required
debug=true userFile="users.xml" groupFile="groups.xml";
};



熟悉您的主體
Subject 類被用于封裝一個被認證實體(比如用戶)的憑證。一個 Subject 可能擁有一個被稱為主體(principal)的身份分組。例如,假如 Subject 是一個用戶,用戶的名字和相關的社會保險號可能是 Subject 的某些身份或主體。主體是與身份名關聯在一起的。

Principal 實現類及其名稱都是在 JAAS 策略文件中指定的。缺省的 JAAS 實現使用的策略文件與 Java 2 實現的策略文件相似 ? 除了每個授權語句必須與至少一個主體關聯在一起。javax.security.auth.Policy 抽象類被用于表示 JAAS 安全性策略。它的缺省實現由 com.sun.security.auth.PolicyFile 提供,在 com.sun.security.auth.PolicyFile 中策略定義在一個文件中。清單 3 是 JAAS 策略文件的一個示例:

清單 3. 示例 JAAS 策略文件

// Example grant entry
grant codeBase "file:/C:/sample.jar", signedby "XYZ",
principal com.ibm.resource.security.auth.Princip// Allow socket actions to any host using port 8080
permission java.net.SocketPermission
"*:8080", "accept, connect, listen, resolve";
// Allows file access (read, write, execute, delete) in
// the user′s home directory.
Permission java.io.FilePermission
"${user.home}/-", "read, write, execute, delete";
};



這個示例與清單 1 中所示的標準 Java 2 策略文件相似。實際上,唯一的不同是主體語句,該語句聲明只有擁有指定主體和主體名字的 subject(用戶)被授予指定的許可權。

再一次,使用系統屬性 java.security.auth.policy 指出 JAAS 策略文件駐留在何處,如下所示:


java -Djava.security.auth.policy=policy.jaas



Subject 類包含幾個方法來作為非凡 subject 執行工作;這些方法如下所示:


public static Object
doAs(Subject subject, java.security.PrivilegedAction action)
public static Object
doAs(Subject subject, java.security.PrivilegedAction action)
throws java.security.PrivilegedActionException



注重,用來保護敏感代碼的方法與“Java 2 代碼源訪問控制”(Java 2 CodeSource Access Control)概述中描述的方法相同。請參閱參考資料部分以了解更多關于 JAAS 中代碼源訪問控制和認證的信息。


JAAS 中的授權
清單 4 顯示一個授權請求的結果,該請求使用清單 3 中顯示的 JAAS 策略文件。假設已經安裝了 SecurityManager,并且 loginContext 已經認證了一個帶有名為“admin”的 com.ibm.resource.security.auth.PrincipalExample 主體的 Subject。

清單 4. 一個簡單的授權請求
public class JaasExample {
public static void main(String[] args) {
...
// where authenticatedUser is a Subject with
// a PrincipalExample named admin.
Subject.doAs(authenticatedUser, new JaasExampleAction());
...
}
}

public class JaasExampleAction implements PrivilegedAction {
public Object run() {
FileWriter fw = new FileWriter("hi.txt");
fw.write("Hello, World!");
fw.close();
}
}



這里,敏感代碼被封裝在 JaasExampleAction 類中。還要注重,調用類不要求為 JaasExampleAction 類代碼源授予許可權,因為它實現了一個 PrivilegedAction。

擴展 JAAS
大多數應用程序都有定制邏輯,它授權用戶不僅僅在類上執行操作,而且還在該類的實例上執行操作。這種授權通常建立在用戶和實例之間的關系上。這是 JAAS 的一個小缺點。然而,幸運的是,這樣設計 JAAS 使得 JAAS 可以擴展。只要做一點工作,我們將可以擴展 JAAS,使其包含一個通用的、類實例級的授權框架。

在文章開頭處我已經說明了,抽象類 javax.security.auth.Policy 被用于代表 JAAS 安全性策略。它的缺省實現是由 com.sun.security.auth.PolicyFile 類提供。PolicyFile 類從 JAAS 格式的文件(象清單 3 中顯示的那個一樣)中讀取策略。

我們需要向這個文件添加一個東西為類實例級授權擴展策略定義:一個與許可權語句相關的可選關系參數。

缺省 JAAS 許可權語句的格式如下:


permission <permission implementation class> [name], [actions];



我們在這個許可權語句的末尾添加一個可選的關系參數來完成策略定義。下面是新許可權語句的格式:


permission <permission implementation class>
[name], [actions], [relationship];



在為類實例級授權擴展 JAAS 時要注重的最重要的一點是:許可權實現類必須有一個帶三個參數的構造函數。第一個參數是名稱參數,第二個是行為參數,最后一個是關系參數。

解析新文件格式
既然文件格式已經改變,就需要一個新的 javax.security.auth.Policy 子類來解析文件。

為簡單起見,我們的示例使用了一個新的 javax.security.auth.Policy 子類 com.ibm.resource.security.auth.XMLPolicyFile,來從 XML 文件讀取策略。在實際的企業應用程序中,關系
數據庫更適合執行這個任務。

使用 XMLPolicyFile 類代替缺省的 JAAS 訪問控制策略實現的最輕易的方法是向 java.security 屬性文件添加 auth.policy.provider=com.ibm.resource.security.auth.XMLPolicyFile 條目。java.security 屬性文件位于 Java 2 平臺運行時的 lib/security 目錄下。清單 5 是與 XMLPolicyFile 類一起使用的樣本 XML 策略文件:

清單 5. 一個 XML 策略文件
<?xml version="1.0"?>
<policy>
<grant codebase="file:/D:/sample_actions.jar">
<principal classname=
"com.ibm.resource.security.auth.PrincipalExample" name="users">
<permission classname=
"com.ibm.resource.security.auth.ResourcePermission"
name="com.ibm.security.sample.Auction"
actions="create" />
<permission classname=
"com.ibm.resource.security.auth.ResourcePermission"
name="com.ibm.security.sample.Auction"
actions="read" />
<permission classname=
"com.ibm.resource.security.auth.ResourcePermission"
name="com.ibm.security.sample.Auction"
actions="write"
relationship="owner" />
<permission classname=
"com.ibm.resource.security.auth.ResourcePermission"
name="com.ibm.security.sample.Bid"
actions="create" />
<permission classname=
"com.ibm.resource.security.auth.ResourcePermission"
name="com.ibm.security.sample.Bid"
actions="read" />
<permission classname=
"com.ibm.resource.security.auth.ResourcePermission"
name="com.ibm.security.sample.Bid"
actions="write"
relationship="owner" />
<permission classname=
"com.ibm.resource.security.auth.ResourcePermission"
name="com.ibm.security.sample.Bid"
actions="accept"
relationship="actionOwner" />
</principal>
</grant>
</policy>



在這個示例策略文件中,任何與名為 PrincipalExample 的用戶有關的用戶(Subject)都可以創建并讀取一個 Auction.class 實例。但是,只有創建該實例的用戶才可以更新(寫)它。這是第三個 permission 元素定義的,該元素包含值為 owner 的 relationship 屬性。Bid.class 實例也是一樣,除了相應 Auction.class 實例的所有者可以更改投標接受標志。

Resource 接口
要求類實例級訪問控制的類必須實現 Resource 接口。該接口的 getOwner() 方法返回類實例的所有者。fulfills(Subject subject, String relationship) 方法被用于處理特定關系。另外,這些類使用 com.ibm.resource.security.auth.ResourcePermission 類保護敏感代碼。例如,Auction 類擁有下列構造函數:


public Auction() {
Permission permission =
new ResourcePermission("com.ibm.security.sample.Auction", "create");
AccessController.checkPermission(permission);
}



所有者關系
ResourcePermission 類的 implies(Permission p) 方法是這個框架的要害。implies() 方法就等同性比較名稱和行為屬性。假如定義了一個關系,那么必須把受保護的類實例(Resource)傳遞到 ResourcePermission 構造函數中。ResourcePermission 類理解所有者關系。它將類實例的所有者與執行代碼的 subject(用戶)進行比較。特定關系被委托給受保護類的 fulfills() 方法。

例如,在清單 5 中所示的 XML 策略文件中,只有 Auction 類實例的所有者可以更新(寫)文件。該類的 setter 方法使用清單 6 中顯示的保護代碼:

清單 6. 運行中的 implies(Permission) 方法
public void setName(String newName) {
Permission permission =
new ResourcePermission("com.ibm.security.sample.Auction", "write", this);
AccessController.checkPermission(permission);
// sensitive code
this.name = newName;
}



被傳遞到 ResourcePermission 構造函數中的 this 引用代表 Auction 類實現的 Resource 接口。由于策略文件中列出的關系是 owner,所以 ResourcePermission 類使用這個引用檢查當前 Subject(用戶)是否擁有與實例所有者相匹配的主體。假如指定了另一個關系,那么 ResourcePermission 類調用 Auction 類的 fulfills(Subject subject, String relationship) 方法。由 Resource 實現類提供 fulfills() 方法中的邏輯。

XML 策略文件中列出的 Bid 類擁有清單 7 中所示的方法(假設 Bid 類實例有一個對相應 Auction 類實例的引用 ? auction)。

清單 7. 處理特定關系
public void setAccepted(boolean flag) {
Permission permission =
new ResourcePermission("com.ibm.security.sample.Auction", "accept", this);
AccessController.checkPermission(permission);
// sensitive code
this.accepted = flag;
}

public boolean fulfills(Subject user, String relationship) {
if( relationship.equalsIgnoreCase("auctionOwner") ) {
String auctionOwner = auction.getOwner();
Iterator principalIterator = user.getPrincipals().iterator();
while(principalIterator.hasNext()) {
Principal principal = (Principal) principalIterator.next();
if( principal.getName().equals(auctionOwner) )
return true;
}
}
return false;
}



傳遞到 fulfills() 方法中的關系字符串是策略文件中列出的關系。在這個案例中,我們使用了“auctionOwner”字符串。

缺省情況下,XMLPolicyFile 類在當前工作目錄中查找名為 ResourcePolicy.xml 的文件。系統屬性 com.ibm.resource.security.auth.policy 可以用于指定另一個不同的文件名和位置。

WebSphere application Server 示例


除命令行示例之外,您可能還想運行這個簡單的程序,該程序為了 IBM WebSphere Application Server,version 4.0.2 而被優化。

一個可運行的示例
綜合這些信息,我們將運行一個簡單的命令行示例。該示例程序包含三個 jar 文件:

resourceSecurity.jar
example.jar
exampleActions.jar
resourceSecurity.jar 文件包含答應實例級訪問控制的 JAAS 擴展框架。它還包含一個 LoginModuleExample 類,這個類從 XML 文件讀取用戶認證信息。用戶標識和密碼存儲在 users.xml 文件中。用戶組存儲在 groups.xml 文件中。關于 LoginModuleExample 的更多信息,請參閱參考資料部分。

該示例包含四個附加的文件:

login.conf
policy
resourcePolicy.xml
run.bat
在試圖運行這個示例程序之前,請確保更新了 run.bat、policy 和 resourcePolicy.xml 文件中的路徑。缺省情況下,所有的密碼都是“passw0rd”。

示例如何工作
該示例程序提示輸入用戶標識和密碼。它用 users.xml 文件中的條目核對所提供的用戶標識和密碼。在認證了用戶之后,程序設法創建一個 UserProfile 類實例,修改它并從中讀取。缺省情況下,UserProfile 類的所有者是 Jane(jane)。當 Jane 登錄時,三個操作全部成功。當 John(john)登錄時,只有創建操作成功。當 Jane 的經理 Lou(lou)登錄時,只有第一個和最后一個操作成功。當系統治理員(admin)登錄時,操作全部成功。當然,只有當提供的 ResourcePolicy.xml 文件未被修改時,上述這些才都是真的。

示例安裝
下面的安裝指導假設您正在使用 JDK 1.3 并且已經把文件解壓縮到 d:JaasExample 目錄。通過將文件解壓縮到這個目錄,您可以省去一些工作;否則您就必須使用正確的路徑名修改 policy 和 ResourceSecurity.xml 策略文件。

下面是運行該示例需要做的工作:

下載這個示例的源文件。


把 jaas.jar 和 jaasmod.jar 復制到 JDK jrelibext 目錄(即 D:JDK1.3jrelibext)。


向位于 JDK 的 jrelibsecurity 目錄(即 D:JDK1.3jrelibsecurity)中的 java.security 文件的末尾添加下面的字符串:auth.policy.provider=com.ibm.resource.security.auth.XMLPolicyFile。


執行 run.bat 文件。

結束語
類實例級授權把訪問控制分離到一個通用框架(該框架使用基于所有權和特定關系的策略)中。然后治理員可以在應用程序的生命周期內更改這些策略。用這種方法擴展 JAAS 減少了您或另一個程序員必須在應用程序生命周期內業務規則發生更改時重寫代碼的可能性。

通過將關系字符串抽象為類可以進一步擴展特定關系這個概念。不調用 Resource 實現類的 fulfills(Subject user, String relationship) 方法,而只要調用 Relationship 實現類中定義的新 fulfills(Subject user, Resource resource) 方法。這樣就會答應許多 Resource 實現類使用相同的關系邏輯。

參考資料

請單擊文章頂部或底部的討論參與本文的討論論壇。


下載本文中所用示例的源代碼。


IBM 的 Preview technologies for Windows 讓您下載放在一個唾手可得的軟件包中的 JDK 1.3 和 WebSphere Application Server。


要了解更多關于“Java 認證和授權服務”的知識,請參閱 JAAS 1.0 Developers Guide。


Java 2 API Documentation 是另一個用于了解 Java 2 平臺擴展的優秀參考資料。


訪問 Sun Microsystems 的 Java 教程系列 Security in Java 2 SDK 1.2(它包括關于策略文件的課程),您可以了解更多關于 Java 平臺的安全性模型的信息。


要進一步了解 Java 平臺的安全性模型背景,請參閱 API for Privileged Blocks,它介紹了特權代碼的概念。


關于 Java 安全性的深入介紹,請參閱 Scott Oaks 的 Java Security, 2nd Edition (O′Reilly & Associates,2001 年 5 月)。


為了更結合實際地學習 JAAS,請參閱 Thomas Owusu 的“Enhance Java GSSAPI with a login interface using JAAS”(developerWorks,2001 年 11 月)


“Single Sign On Support in WebSphere Portal Server 1.2”討論了 WebSphere Portal Server 的 JAAS 實現并展示了如何抽取用戶數據并將其提供給一個 portlet 的后端應用程序,或者提供給同一個安全性域中的另一個 WebSphere Application Server。


假如您想深入了解 IBM 在 Java 安全性的發展中所起的歷史性作用,請參閱文章“The evolution of Java security”,在這篇文章中 IBM 工程師討論了 JDK 1.2 安全性模型的優缺點。


您將在 IBM developerWorks Java 技術專區找到數百篇關于 Java 編程各個方面的文章。

關于作者
Carlos Fonseca 目前是 IBM Research 的軟件工程師,他已經做了 10 年的專職軟件開發工作。他開始是從事 C 和 Visual Basic 編程,然后轉向 C++ 編程。在最近六年中,Carlos 致力于面向對象的設計和使用 Java 平臺進行開發,把他的專業技術應用于從 Swing GUI 單機應用程序到使用 J2EE 的服務器端應用程序等項目。當 Carlos 不再從事專業軟件開發時,他還喜歡把編程作為業余愛好。您可以通過 cafonseca@us.ibm.com 與 Carlos 聯系。

--摘自IBM網站
http://www-900.ibm.com/developerWorks/cn/java/j-jaas/index.sHtml

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 郯城县| 松溪县| 沁阳市| 彰武县| 佳木斯市| 曲沃县| 大荔县| 乌拉特中旗| 南乐县| 新泰市| 兴城市| 重庆市| 邹城市| 星子县| 胶南市| 库伦旗| 西藏| 肃北| 当涂县| 嘉善县| 乃东县| 朝阳县| 高青县| 神木县| 武夷山市| 尉犁县| 吉木乃县| 孟村| 霸州市| 育儿| 河池市| 商城县| 金溪县| 通河县| 怀来县| 东兰县| 固原市| 乡城县| 巴林左旗| 图们市| 于田县|