最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot集成Spring Security的方法

 更新時(shí)間:2020年07月06日 09:43:10   作者:良許Linux  
Spring security,是一個(gè)強(qiáng)大的和高度可定制的身份驗(yàn)證和訪問控制框架。這篇文章主要介紹了SpringBoot集成Spring Security的操作方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

至今Java能夠如此的火爆Spring做出了很大的貢獻(xiàn),它的出現(xiàn)讓Java程序的編寫更為簡單靈活,而Spring如今也形成了自己的生態(tài)圈,今天咱們探討的是Spring旗下的一個(gè)款認(rèn)證工具:SpringSecurity,如今認(rèn)證框架主流“shiro”和“SpringSecurity”,由于和Spring的無縫銜接,使用SpringSecurity的企業(yè)也越來越多。

1、Spring Security介紹

Spring security,是一個(gè)強(qiáng)大的和高度可定制的身份驗(yàn)證和訪問控制框架。它是確?;赟pring的應(yīng)用程序的標(biāo)準(zhǔn)——來自官方參考手冊

Spring security 和 shiro 一樣,具有認(rèn)證、授權(quán)、加密等用于權(quán)限管理的功能。和 shiro 不同的是,Spring security擁有比shiro更豐富的功能,并且,對于Springboot而言,Spring Security比Shiro更合適一些,因?yàn)槎际荢pring家族成員。今天,我們來為SpringBoot項(xiàng)目集成Spring Security。

本文所使用的版本:

​SpringBoot : 2.2.6.RELEASE
​Spring Security : 5.2.2.RELEASE

2、配置Spring Security

在SpringBoot中集成Spring Security很簡單,只需要在pom.xml中添加下面代碼就行:

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

這里可以不指定Spring Security的版本號,它會根據(jù)SpringBoot的版本來匹配對應(yīng)的版本,SpringBoot版本是 2.2.6.RELEASE,對應(yīng)Spring Security的版本是5.2.2.RELEASE。

然后,我們就可以將springboot啟動(dòng)了。

當(dāng)我們嘗試訪問項(xiàng)目時(shí),它會跳轉(zhuǎn)到這個(gè)界面來:

​對!在此之前,你什么也不用做。這就是Spring Security的優(yōu)雅之處。你只需要引入Spring Security的包,它就能在你的項(xiàng)目中工作。因?yàn)樗呀?jīng)幫你實(shí)現(xiàn)了一個(gè)簡單的登陸界面。根據(jù)官方介紹,登錄使用的賬號是user,密碼是隨機(jī)密碼,這個(gè)隨機(jī)密碼可以在控制臺中找到,類似這樣的一句話:

Using generated security password: 1cb77bc5-8d74-4846-9b6c-4813389ce096

​Using generated security password后面的的就是系統(tǒng)給的隨機(jī)密碼,我們可以使用這個(gè)密碼進(jìn)行登錄。隨機(jī)密碼在每一次啟動(dòng)服務(wù)后生成(如果你配置了熱部署devtools,你得隨時(shí)留意控制臺了,因?yàn)槊慨?dāng)你修改了代碼,系統(tǒng)會自動(dòng)重啟,那時(shí)隨機(jī)密碼就會重新生成)。

​當(dāng)然,這樣的功能一定不是你想要的,也一定不會就這樣拿給你的用戶使用。那么,接下來,讓我們把它配置成我們想要的樣子。

​要實(shí)現(xiàn)自定義配置,首先要?jiǎng)?chuàng)建一個(gè)繼承于WebSecurityConfigurerAdapter的配置類:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

}

​這里使用了@EnableWebSecurity注解,這個(gè)注解是Spring Security用于啟用web安全的注解。具體實(shí)現(xiàn),這里就不深入了。

​要實(shí)現(xiàn)自定義攔截配置,首先得告訴Spring Security,用戶信息從哪里獲取,以及用戶對應(yīng)的角色等信息。這里就需要重寫WebSecurityConfigurerAdapter的configure(AuthenticationManagerBuilder auth)方法了。這個(gè)方法將指使Spring Security去找到用戶列表,然后再與想要通過攔截器的用戶進(jìn)行比對,再進(jìn)行下面的步驟。

​Spring Security的用戶存儲配置有多個(gè)方案可以選擇,包括:

  • 內(nèi)存用戶存儲
  • 數(shù)據(jù)庫用戶存儲
  • LDAP用戶存儲
  • 自定義用戶存儲

​我們分別來看看這幾種用戶存儲的配置方法:

1.內(nèi)存用戶存儲

​此配置方式是直接將用戶信息存儲在內(nèi)存中,這種方式在速度上無疑是最快的。但只適用于有限個(gè)用戶數(shù)量,且這些用戶幾乎不會發(fā)生改變。我們來看看配置方法:

@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.inMemoryAuthentication().passwordEncoder(passwordEncoder())
			.withUser("zhangsan").password(passwordEncoder().encode("123456")).authorities("ADMIN")
			.and()
			.withUser("lisi").password(passwordEncoder().encode("123456")).authorities("ORDINARY");
	}
	
	private PasswordEncoder passwordEncoder() {
  return new BCryptPasswordEncoder();
 }

​可以看到,AuthenticationManagerBuilder使用構(gòu)造者方式來構(gòu)建的。在上面方法中,先調(diào)用了inMemoryAuthentication()方法,它來指定用戶存儲在內(nèi)存中。接下來又調(diào)用了passwordEncoder()方法,這個(gè)方法的作用是告訴Spring Security認(rèn)證密碼的加密方式。因?yàn)樵赟pring security5過后,必須指定某種加密方式,不然程序會報(bào)錯(cuò)。接下來調(diào)用的withUser()、password()、authorities()方法,分別是在指定用戶的賬號、密碼以及權(quán)限名。在添加完一個(gè)用戶后,要使用and()方法來連接下一個(gè)用戶的添加。

​如果使用這種配置方法,你會發(fā)現(xiàn),在修改用戶時(shí),就必須修改代碼。對于絕大多數(shù)項(xiàng)目來說,這種方式是滿足不了需求的,至少我們需要一個(gè)注冊功能。

2.數(shù)據(jù)庫用戶存儲

​將用戶信息存儲在數(shù)據(jù)庫中,讓我們可以很方便地對用戶信息進(jìn)行增刪改查。并且還可以為用戶添加除認(rèn)證信息外的附加信息,這樣的設(shè)計(jì)也是我們很多小心應(yīng)用所采取的方式。讓我們來實(shí)現(xiàn)以下:

@Autowired
	private DataSource dataSource;
	
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder())
			.usersByUsernameQuery(
					"select username, password, status from Users where username = ?")
			.authoritiesByUsernameQuery(
					"select username, authority from Authority where username = ?");
		
	}
	
	private PasswordEncoder passwordEncoder() {
  return new BCryptPasswordEncoder();
 }

​調(diào)用jdbcAuthentication()來告訴Spring Security使用jdbc的方式來查詢用戶和權(quán)限,dataSource()方法指定數(shù)據(jù)庫連接信息,passwordEncoder()指定密碼加密規(guī)則,用戶的密碼數(shù)據(jù)應(yīng)該以同樣的方式進(jìn)行加密存儲,不然,兩個(gè)加密方式不同的密碼,匹配補(bǔ)上。usersByUsernameQuery()和authoritiesByUsernameQuery()方法分別定義了查詢用戶和權(quán)限信息的sql語句。其實(shí),Spring security為我們默認(rèn)了查詢用戶、權(quán)限甚至還有群組用戶授權(quán)的sql,這三條默認(rèn)的sql存放在org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl中,有興趣的小伙伴可以點(diǎn)進(jìn)去看看。如果你要使用默認(rèn)的,那你的表中關(guān)鍵性的字段必須和語句中的一致。

​使用數(shù)據(jù)庫來存儲用戶和權(quán)限等信息已經(jīng)可以滿足大部分的需求。但是Spring security還為我們提供了另外一種配置方式,讓我們來看一下。

3.LDAP用戶存儲

​LDAP:輕型目錄訪問協(xié)議,是一個(gè)開放的,中立的,工業(yè)標(biāo)準(zhǔn)的應(yīng)用協(xié)議,通過IP協(xié)議提供訪問控制和維護(hù)分布式信息的目錄信息。簡單來說,就是將用戶信息存放在另外一臺服務(wù)器中(當(dāng)然,也可以在同一臺服務(wù)器,但我們一般不這么做),通過網(wǎng)絡(luò)來進(jìn)行訪問的技術(shù)。

​我們來簡單配置一下:

@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		LdapAuthenticationProviderConfigurer<AuthenticationManagerBuilder> configurer = 					auth.ldapAuthentication()
			.userSearchBase("ou=people")
			.userSearchFilter("(uid={0})")
			.groupSearchBase("ou=groups")
			.groupSearchFilter("member={0}");
			
		configurer.passwordCompare()
			.passwordEncoder(passwordEncoder())
			.passwordAttribute("passcode");
		configurer.contextSource().url("ldap://xxxxx.com:33389/dc=xxxxxx,dc=com");
	}
	
	private PasswordEncoder passwordEncoder() {
  return new BCryptPasswordEncoder();
 }

​userSearchFilter()和groupSearchFilter()設(shè)置的是用戶和群組的過濾條件,而userSearchBase()和groupSearchBase()設(shè)置了搜索起始位置,contextSource().url()設(shè)置LDAP服務(wù)器的地址。如果沒有遠(yuǎn)程的服務(wù)器可以使用contextSource().root()來使用嵌入式LDAP服務(wù)器,此方式將使用項(xiàng)目中的用戶數(shù)據(jù)文件來提供認(rèn)證服務(wù)。

​如果以上幾種方式還不能滿足我們的需求,我們可以用自定義的方式來配置。

4.自定義用戶存儲

​自定義用戶存儲,就是自行使用認(rèn)證名稱來查找對應(yīng)的用戶數(shù)據(jù),然后交給Spring Security使用。我們需要定義一個(gè)實(shí)現(xiàn)UserDetailsService的service類:

@Service
public class MyUserDetailsService implements UserDetailsService{

	@Autowired
	private UserMapper userMapper;
	
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		User user = userMapper.getUserByUsername(username);
		return user == null ? new User() : user;
	}
}

public class User implements UserDetails {
 ...
}

​該類只需要實(shí)現(xiàn)一個(gè)方法:loadUserByUsername()。該方法需要做的是使用傳過來的username來匹配一個(gè)帶有密碼等信息的用戶實(shí)體。需要注意的是這里的User類需要實(shí)現(xiàn)UserDetails,也就是說,查到的信息里,必須得有Spring Security所需要的信息。

​下面,讓我們來繼續(xù)配置:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	private MyUserDetailsService userDetailsService;
	
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(userDetailsService)
			.passwordEncoder(passwordEncoder());
	}
	
	@Bean
	private PasswordEncoder passwordEncoder() {
  return new BCryptPasswordEncoder();
 }
}

​這樣的配置方法就很簡單了,只需要告訴Spring Security你的UserDetailsService實(shí)現(xiàn)類是哪個(gè)就可以了,它會去調(diào)用loadUserByUsername()來查找用戶。

​以上就是Spring Security所提供的4種用戶存儲方式,接下來,需要考慮的是,怎么攔截請求。

3、請求攔截

1.安全規(guī)則

​Spring Security的請求攔截配置方法是用戶存儲配置方法的重載方法,我們先來簡單配置一下:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests()
			.antMatchers("/user", "/menu")
			.hasRole("ADMIN")
			.antMatchers("/", "/**").permitAll();
	}
}

​調(diào)用authorizeRequests()方法后,就可以添加自定義攔截路徑了。antMatchers()方法配置了請求路徑,hasRole()和permitAll()指定了訪問規(guī)則,分別表示擁有“ADMIN”權(quán)限的用戶才能訪問、所有用戶可以訪問。

​需要注意的是:這里的配置需要成對出現(xiàn),并且配置的順序也很重要。聲明在前面的規(guī)則擁有更高的優(yōu)先級。也就是說,如果我們將.antMatchers("/", "/").permitAll()**放到了最前面,像這樣:

@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests()
			.antMatchers("/", "/**").permitAll()
    .antMatchers("/user", "/menu")
			.hasRole("ADMIN");
	}

​那么,下面的"/user"和 "/menu"的配置是徒勞,因?yàn)榍懊娴囊?guī)則已經(jīng)指明所有路徑能被所有人訪問。當(dāng)然權(quán)限的規(guī)則方法還有很多,我這里只列舉了兩個(gè)。以下為常見的內(nèi)置表達(dá)式:

表達(dá) 描述
hasRole(String role) 返回true當(dāng)前委托人是否具有指定角色。例如, hasRole('admin')默認(rèn)情況下,如果提供的角色不是以“ ROLE_”開頭,則會添加該角色。可以通過修改defaultRolePrefixon來自定義DefaultWebSecurityExpressionHandler。
hasAnyRole(String… roles) 返回true當(dāng)前委托人是否具有提供的任何角色(以逗號分隔的字符串列表形式)。例如, hasAnyRole('admin', 'user')默認(rèn)情況下,如果提供的角色不是以“ ROLE_”開頭,則會添加該角色??梢酝ㄟ^修改defaultRolePrefixon來自定義DefaultWebSecurityExpressionHandler。
hasAuthority(String authority) 返回true當(dāng)前委托人是否具有指定權(quán)限。例如, hasAuthority('read')
hasAnyAuthority(String… authorities) 返回true如果當(dāng)前主體具有任何所提供的當(dāng)局的(給定為逗號分隔的字符串列表)例如, hasAnyAuthority('read', 'write')
principal 允許直接訪問代表當(dāng)前用戶的主體對象
authentication 允許直接訪問Authentication從SecurityContext
permitAll 始終評估為 true
denyAll 始終評估為 false
isAnonymous() 返回true當(dāng)前委托人是否為匿名用戶
isRememberMe() 返回true當(dāng)前主體是否是“記住我”的用戶
isAuthenticated() true如果用戶不是匿名的,則返回
isFullyAuthenticated() 返回true如果用戶不是匿名或記得,我的用戶
hasPermission(Object target, Object permission) 返回true用戶是否可以訪問給定權(quán)限的給定目標(biāo)。例如,hasPermission(domainObject, 'read')
hasPermission(Object targetId, String targetType, Object permission) 返回true用戶是否可以訪問給定權(quán)限的給定目標(biāo)。例如,hasPermission(1, 'com.example.domain.Message', 'read')

除此之外,還有一個(gè)支持SpEL表達(dá)式計(jì)算的方法,它的使用方法如下:

@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests()
			.antMatchers("/user", "/menu")
			.access("hasRole('ADMIN')")
			.antMatchers("/", "/**").permitAll();
	}

​它所實(shí)現(xiàn)的規(guī)則和上面的方法一樣。Spring Security還提供了其他豐富的SpEL表達(dá)式,如:

表達(dá) 描述
hasRole(String role) 返回true當(dāng)前委托人是否具有指定角色。例如, hasRole('admin')默認(rèn)情況下,如果提供的角色不是以“ ROLE_”開頭,則會添加該角色??梢酝ㄟ^修改defaultRolePrefixon來自定義DefaultWebSecurityExpressionHandler。
hasAnyRole(String… roles) 返回true當(dāng)前委托人是否具有提供的任何角色(以逗號分隔的字符串列表形式)。例如, hasAnyRole('admin', 'user')默認(rèn)情況下,如果提供的角色不是以“ ROLE_”開頭,則會添加該角色??梢酝ㄟ^修改defaultRolePrefixon來自定義DefaultWebSecurityExpressionHandler。
hasAuthority(String authority) 返回true當(dāng)前委托人是否具有指定權(quán)限。例如, hasAuthority('read')
hasAnyAuthority(String… authorities) 返回true如果當(dāng)前主體具有任何所提供的當(dāng)局的(給定為逗號分隔的字符串列表)例如, hasAnyAuthority('read', 'write')
principal 允許直接訪問代表當(dāng)前用戶的主體對象
authentication 允許直接訪問Authentication從SecurityContext
permitAll 始終評估為 true
denyAll 始終評估為 false
isAnonymous() 返回true當(dāng)前委托人是否為匿名用戶
isRememberMe() 返回true當(dāng)前主體是否是“記住我”的用戶
isAuthenticated() true如果用戶不是匿名的,則返回
isFullyAuthenticated() 返回true如果用戶不是匿名或記得,我的用戶
hasPermission(Object target, Object permission) 返回true用戶是否可以訪問給定權(quán)限的給定目標(biāo)。例如,hasPermission(domainObject, 'read')
hasPermission(Object targetId, String targetType, Object permission) 返回true用戶是否可以訪問給定權(quán)限的給定目標(biāo)。例如,hasPermission(1, 'com.example.domain.Message', 'read')

2.登錄

​如果此時(shí),我們有自己的登錄界面,需要替換掉Spring Security所提供的默認(rèn)的界面,這時(shí)可以用fromLogin()和loginPage()方法來實(shí)現(xiàn):

@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests()
			.antMatchers("/user", "/menu")
			.access("hasRole('ADMIN')")
			.antMatchers("/", "/**").permitAll()
			.and()
			.formLogin()
			.loginPage("/login");
	}

​這便將登錄地址指向了“/login”。如果需要指定登錄成功時(shí),跳轉(zhuǎn)的地址,可以使用defaultSuccessUrl()方法:

 .and()
   .formLogin()
   .loginPage("/login")
   .defaultSuccessUrl("/home")

​此時(shí)用戶登錄過后,將跳轉(zhuǎn)到主頁來。

​下面,我們來看看登出。

3.登出

​和登錄類似的,可以使用logout()和logoutSuccessUrl()方法來實(shí)現(xiàn):

.and()
			.logout()
			.logoutSuccessUrl("/login")

​上面例子中,用戶登出后將跳轉(zhuǎn)到登錄界面。

4、小結(jié)

​至此,我們已基本了解了Spring Security配置,可以將它配置成我們想要的樣子(基本)。其實(shí)Spring Security能做的事還有很多,光看我這篇文章是不夠的。學(xué)習(xí)它最有效的方法就是閱讀官方文檔。里面有關(guān)于Spring Security最全最新的知識?。ü倬W(wǎng)地址:https://spring.io/projects/spring-security)

到此這篇關(guān)于SpringBoot集成Spring Security的文章就介紹到這了,更多相關(guān)SpringBoot集成Spring Security內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java 學(xué)習(xí)筆記(入門篇)_java程序helloWorld

    java 學(xué)習(xí)筆記(入門篇)_java程序helloWorld

    安裝配置完Java的jdk,下面就開始寫第一個(gè)java程序--hello World.用來在控制臺輸出“Hello World”,接下來詳細(xì)介紹,感興趣的朋友可以參考下
    2013-01-01
  • Java內(nèi)部類的實(shí)現(xiàn)原理與可能的內(nèi)存泄漏說明

    Java內(nèi)部類的實(shí)現(xiàn)原理與可能的內(nèi)存泄漏說明

    這篇文章主要介紹了Java內(nèi)部類的實(shí)現(xiàn)原理與可能的內(nèi)存泄漏說明,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • Java導(dǎo)出網(wǎng)頁表格Excel過程詳解

    Java導(dǎo)出網(wǎng)頁表格Excel過程詳解

    這篇文章主要介紹了Java導(dǎo)出網(wǎng)頁表格Excel過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Java實(shí)戰(zhàn)玩具商城的前臺與后臺實(shí)現(xiàn)流程

    Java實(shí)戰(zhàn)玩具商城的前臺與后臺實(shí)現(xiàn)流程

    讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+JSP+SSM+Springboot+Jsp+maven+Mysql實(shí)現(xiàn)一個(gè)玩具商城系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平
    2022-01-01
  • 利用Java搭建個(gè)簡單的Netty通信實(shí)例教程

    利用Java搭建個(gè)簡單的Netty通信實(shí)例教程

    這篇文章主要給大家介紹了關(guān)于如何利用Java搭建個(gè)簡單的Netty通信,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Java使用Gateway自定義負(fù)載均衡過濾器

    Java使用Gateway自定義負(fù)載均衡過濾器

    這篇文章主要介紹了Java使用Gateway自定義負(fù)載均衡過濾器,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java觀察者模式例子

    Java觀察者模式例子

    這篇文章主要介紹了Java觀察者模式例子的相關(guān)資料,需要的朋友可以參考下
    2015-12-12
  • Java實(shí)現(xiàn)郵件發(fā)送功能

    Java實(shí)現(xiàn)郵件發(fā)送功能

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)郵件發(fā)送功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Java設(shè)計(jì)模式之模板方法詳解

    Java設(shè)計(jì)模式之模板方法詳解

    模板方法的概念:定義了一個(gè)操作中的算法的骨架,而將部分步驟的實(shí)現(xiàn)在子類中完成。模板方法模式使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟
    2022-07-07
  • SpringBoot使用Validation校驗(yàn)參數(shù)的詳細(xì)過程

    SpringBoot使用Validation校驗(yàn)參數(shù)的詳細(xì)過程

    這篇文章主要介紹了SpringBoot使用Validation校驗(yàn)參數(shù),本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09

最新評論

南华县| 卢氏县| 唐山市| 柘城县| 天长市| 白山市| 湘潭县| 牡丹江市| 安塞县| 渝北区| 谷城县| 中阳县| 阿图什市| 介休市| 阿瓦提县| 特克斯县| 津市市| 新乡市| 晋宁县| 名山县| 仲巴县| 习水县| 南昌县| 富锦市| 黔西县| 定州市| 家居| 靖西县| 久治县| 青川县| 太仓市| 新邵县| 公主岭市| 河北区| 桦南县| 尚志市| 延吉市| 常州市| 锡林郭勒盟| 新竹市| 淮北市|