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

一文帶你掌握Spring Security框架的使用

 更新時(shí)間:2023年05月12日 15:34:57   作者:蜀山劍客李沐白  
Spring Security是一款基于Spring框架的認(rèn)證和授權(quán)框架,提供了一系列控制訪問(wèn)和保護(hù)應(yīng)用程序的功能,本文將會(huì)對(duì)Spring Security框架進(jìn)行全面詳細(xì)的講解,需要的可以參考下

Spring Security是一款基于Spring框架的認(rèn)證和授權(quán)框架,提供了一系列控制訪問(wèn)和保護(hù)應(yīng)用程序的功能,同時(shí)也支持基于角色和權(quán)限的訪問(wèn)控制,加密密碼,CSRF防范,會(huì)話管理等多種功能。Spring Security可以輕松地與其他Spring框架,如Spring Boot和Spring MVC進(jìn)行集成使用。

本文將會(huì)對(duì)Spring Security框架進(jìn)行全面詳細(xì)的講解,包括框架的概述、認(rèn)證、授權(quán)、LDAP身份驗(yàn)證、Kerberos身份驗(yàn)證、CSRF防范、加密密碼、會(huì)話管理、異常處理等方面,并提供相關(guān)API。

框架概述

Spring Security是一個(gè)基于Spring框架的認(rèn)證和授權(quán)框架,它提供了各種工具和框架來(lái)保護(hù)基于Spring的應(yīng)用程序。Spring Security可以讓開(kāi)發(fā)人員和系統(tǒng)管理員輕松地配置各種安全功能,例如:

  • 用戶認(rèn)證和授權(quán)
  • 保護(hù)Web應(yīng)用免受各種攻擊,如跨站點(diǎn)腳本攻擊(XSS)、跨站點(diǎn)請(qǐng)求偽造攻擊(CSRF)和點(diǎn)擊劫持攻擊
  • 使用基于角色和權(quán)限的訪問(wèn)控制來(lái)保護(hù)應(yīng)用程序資源
  • 帶有單點(diǎn)登錄(SSO)功能,可以將多個(gè)應(yīng)用程序集成到一個(gè)中央身份驗(yàn)證系統(tǒng)
  • 與其他Spring框架,如Spring MVC和Spring Boot,提供可定制的集成

正如其名字所示,Spring Security是將安全性融入了Spring生態(tài)系統(tǒng)中,這樣就可以輕松地使用Spring的依賴注入和面向切面編程等強(qiáng)大功能來(lái)管理應(yīng)用程序的安全性。

Spring Security的架構(gòu)

Spring Security的架構(gòu)如下所示:

+-----------------+
| Security Filter |
+-----------------+
        |
+-----------------+
| Web Security    |
+-----------------+
        |
+-----------------+
| Authentication  |
+-----------------+
        |
+-----------------+
| Access Control  |
+-----------------+

  • Security Filter:是整個(gè)Spring Security架構(gòu)的基礎(chǔ)。它是作為第一條鏈的Servlet過(guò)濾器。所有的安全相關(guān)操作都是在Security Filter之后執(zhí)行的。
  • Web Security:是通過(guò)“HttpSecurity”對(duì)象實(shí)現(xiàn)的,它是框架的核心子系統(tǒng),負(fù)責(zé)身份驗(yàn)證、授權(quán)和安全事件的處理等工作。Web Security通常與Spring MVC或Spring Boot集成使用。
  • Authentication:是指Spring Security處理身份驗(yàn)證的核心功能。它包括身份驗(yàn)證提供者、令牌和身份驗(yàn)證流程等組件。使用Spring Security,開(kāi)發(fā)者可以選擇多種身份驗(yàn)證方法,如HTTP Basic認(rèn)證、表單登錄、OpenID Connect等。
  • Access Control:是指Spring Security控制資源訪問(wèn)的核心功能。它使用“AccessDecisionManager”接口來(lái)決定用戶是否有權(quán)限訪問(wèn)受保護(hù)的資源,同時(shí)支持基于角色和基于權(quán)限的訪問(wèn)控制。

Spring Security的主要特點(diǎn)

Spring Security具有以下主要特點(diǎn):

  • 支持多種身份驗(yàn)證方式:Spring Security支持多種身份驗(yàn)證方式,如HTTP身份驗(yàn)證、基本表單登錄、OpenID Connect等。
  • 用于訪問(wèn)控制的靈活而強(qiáng)大的體系結(jié)構(gòu):Spring Security提供了基于角色和基于權(quán)限的授權(quán)方式,可以輕松地控制和管理資源訪問(wèn)。
  • 安全防范功能:Spring Security提供了多種安全防范功能,如CSRF防范、XSS防范、會(huì)話管理等,以保證應(yīng)用程序的安全性。
  • 可擴(kuò)展性和可定制性:Spring Security是一個(gè)高度可定制的框架,允許應(yīng)用程序開(kāi)發(fā)人員對(duì)其進(jìn)行擴(kuò)展和自定義以滿足自己的需求。
  • 集成其他Spring框架:Spring Security可以輕松地與其他Spring框架,如Spring Boot和Spring MVC集成,使得使用Spring生態(tài)系統(tǒng)的開(kāi)發(fā)人員無(wú)縫集成安全功能。

認(rèn)證

認(rèn)證是Spring Security框架的一個(gè)核心功能,它是通過(guò)身份驗(yàn)證來(lái)確定用戶的身份。Spring Security支持多種身份驗(yàn)證方式,如HTTP Basic認(rèn)證、表單登錄、OpenID Connect等。

HTTP Basic認(rèn)證

HTTP Basic認(rèn)證是一種簡(jiǎn)單的身份驗(yàn)證方式,它將用戶名和密碼作為HTTP請(qǐng)求的頭部信息發(fā)送給服務(wù)器進(jìn)行驗(yàn)證。我們可以通過(guò)“HttpSecurity”對(duì)象實(shí)現(xiàn)HTTP Basic認(rèn)證。

@Configuration
@EnableWebSecurity
public class HttpBasicSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .httpBasic();
    }
}

在上面的例子中,我們使用了Spring Security的Java配置方式來(lái)配置HTTP Basic認(rèn)證。我們首先使用“authorizeRequests()”方法定義了所有請(qǐng)求都需要進(jìn)行身份驗(yàn)證。然后,使用“httpBasic()”方法開(kāi)啟了HTTP Basic認(rèn)證。

表單登錄

在Spring Security中,我們也可以使用傳統(tǒng)的用戶名和密碼表單登錄來(lái)進(jìn)行身份驗(yàn)證。通過(guò)表單登錄,用戶可以在Web應(yīng)用程序的自定義登錄頁(yè)面中輸入用戶名和密碼。

首先,我們需要使用“formLogin()”方法定義登錄頁(yè)面和處理URL:

@Configuration
@EnableWebSecurity
public class FormLoginSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .loginProcessingUrl("/auth")
                .defaultSuccessUrl("/home")
                .failureUrl("/login?error=true")
                .usernameParameter("username")
                .passwordParameter("password");
    }
}

在上面的例子中,我們使用“formLogin()”方法定義了登錄頁(yè)面和處理URL。我們首先允許所有用戶訪問(wèn)"/login"頁(yè)面,然后使用“loginPage()”方法定義了登錄頁(yè)面的URL;使用“loginProcessingUrl()”方法定義了登錄處理URL。最后,使用“defaultSuccessUrl()”方法和“failureUrl()”方法定義登錄成功和失敗后的重定向頁(yè)面。我們還可以使用“usernameParameter()”方法和“passwordParameter()”方法自定義表單中的用戶名和密碼輸入框的name屬性。

在Spring Security中,我們也可以使用@Component注解將LoginForm定義為一個(gè)Spring Bean,以方便使用。示例代碼如下:

@Component
public class LoginForm extends UsernamePasswordAuthenticationToken {
	private String username;
	private String password;
	public LoginForm(String username, String password) {
		super(username, password);
		this.username = username;
		this.password = password;
	}
	@Override
	public Object getCredentials() {
		return password;
	}
	@Override
	public Object getPrincipal() {
		return username;
	}
}

OpenID Connect

OpenID Connect是一種基于OAuth2協(xié)議的身份驗(yàn)證和授權(quán)協(xié)議,它適用于Web應(yīng)用程序、移動(dòng)應(yīng)用程序和IoT設(shè)備等場(chǎng)景。Spring Security提供了對(duì)OpenID Connect的支持,我們可以使用“OAuth2LoginConfigurer”實(shí)現(xiàn)OpenID Connect認(rèn)證。

首先,我們需要定義一個(gè)OAuth2 Client Registration:

@Configuration
public class OidcConfiguration {
    @Bean
    public ClientRegistration oidcClientRegistration() {
        return ClientRegistration.withRegistrationId("oidc")
                .clientId("my-client-id")
                .clientSecret("my-client-secret")
                .redirectUriTemplate("{baseUrl}/login/oauth2/code/{registrationId}")
                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                .scope("openid", "profile", "email", "address", "phone")
                .authorizationUri("https://accounts.google.com/o/oauth2/auth")
                .tokenUri("https://www.googleapis.com/oauth2/v4/token")
                .userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
                .userNameAttributeName(IdTokenClaimNames.SUB)
                .jwkSetUri("https://www.googleapis.com/oauth2/v3/certs")
                .clientName("Google")
                .build();
    }
}

在上面的例子中,我們使用“ClientRegistration”對(duì)象定義了OpenID Connect客戶端的信息,包括客戶端ID、客戶端密鑰、重定向URI、授權(quán)類型、作用域、授權(quán)服務(wù)器URI、令牌URI、用戶信息URI、用戶名屬性名稱、JWK公鑰集等。

然后,在Spring Security中,我們需要使用“OAuth2LoginConfigurer”配置OpenID Connect認(rèn)證:

@Configuration
@EnableWebSecurity
public class OidcSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private ClientRegistration oidcClientRegistration;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .oauth2Login()
                .clientRegistrationRepository(clientRegistrationRepository())
                .userInfoEndpoint()
                    .oidcUserService(oidcUserService());
    }
    private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() {
        return new OidcUserService();
    }
    private ClientRegistrationRepository clientRegistrationRepository() {
        return new InMemoryClientRegistrationRepository(Collections.singletonList(oidcClientRegistration));
    }
}

在上面的例子中,我們使用了“OAuth2LoginConfigurer”方法開(kāi)啟了OpenID Connect認(rèn)證,同時(shí)使用了“clientRegistrationRepository()”方法和“oidcUserService()”方法配置OAuth2 Client Registration和OAuth2 User Service。

授權(quán)

Spring Security提供了基于角色和基于權(quán)限的訪問(wèn)控制,包括:

基于角色的訪問(wèn)控制

Spring Security使用角色來(lái)組織應(yīng)用程序中的訪問(wèn)控制。我們可以使用“hasRole()”方法來(lái)實(shí)現(xiàn)基于角色的訪問(wèn)控制。示例代碼如下:

@Configuration
@EnableWebSecurity
public class RoleBasedSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/user/**").hasRole("USER")
                .anyRequest().authenticated()
                .and()
            .formLogin();
    }
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("admin").password("{noop}admin123").roles("ADMIN")
                .and()
                .withUser("user").password("{noop}user123").roles("USER");
    }
}

在上面的例子中,我們使用了“hasRole()”方法定義了"/admin/"和"/user/"路徑需要ADMIN和USER角色才能訪問(wèn)。然后,我們使用“configureGlobal()”方法配置了用戶信息,包括用戶名、密碼和角色。

基于權(quán)限的訪問(wèn)控制

Spring Security也支持基于權(quán)限的訪問(wèn)控制,我們可以使用“hasAuthority()”方法來(lái)實(shí)現(xiàn)基于權(quán)限的訪問(wèn)控制。示例代碼如下:

@Configuration
@EnableWebSecurity
public class PermissionBasedSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/admin/**").hasAuthority("ADMIN")
                .antMatchers("/user/**").hasAuthority("USER")
                .anyRequest().authenticated()
                .and()
            .formLogin();
    }
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("admin").password("{noop}admin123").authorities("ADMIN")
                .and()
                .withUser("user").password("{noop}user123").authorities("USER");
    }
}

在上面的例子中,我們使用了“hasAuthority()”方法定義了"/admin/"和"/user/"路徑需要ADMIN和USER權(quán)限才能訪問(wèn)。然后,我們使用“configureGlobal()”方法配置了用戶信息,包括用戶名、密碼和權(quán)限。

表達(dá)式語(yǔ)言

除了使用“hasRole()”方法和“hasAuthority()”方法來(lái)實(shí)現(xiàn)基于角色和基于權(quán)限的訪問(wèn)控制之外,Spring Security還支持使用表達(dá)式語(yǔ)言進(jìn)行訪問(wèn)控制。我們可以使用“access()”方法來(lái)實(shí)現(xiàn)基于表達(dá)式語(yǔ)言的訪問(wèn)控制。示例代碼如下:

@Configuration
@EnableWebSecurity
public class ExpressionBasedSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/admin/**").access("hasRole('ADMIN')")
                .antMatchers("/user/**").access("hasRole('USER') or hasIpAddress('127.0.0.1')")
                .anyRequest().authenticated()
                .and()
            .formLogin();
    }
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("admin").password("{noop}admin123").roles("ADMIN")
                .and()
                .withUser("user").password("{noop}user123").roles("USER");
    }
}

在上面的例子中,我們使用了“access()”方法定義了"/admin/"和"/user/"路徑的訪問(wèn)控制規(guī)則。其中,我們通過(guò)“hasRole()”表達(dá)式實(shí)現(xiàn)了對(duì)ADMIN角色的要求,同時(shí)通過(guò)“hasIpAddress()”表達(dá)式實(shí)現(xiàn)了對(duì)特定IP地址的允許。

LDAP身份驗(yàn)證

Spring Security也支持LDAP身份驗(yàn)證,我們可以使用“LdapAuthenticationConfigurer”來(lái)實(shí)現(xiàn)LDAP身份驗(yàn)證。示例代碼如下:

@Configuration
@EnableWebSecurity
public class LdapSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .formLogin();
    }
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .ldapAuthentication()
                .userDnPatterns("uid={0},ou=people")
                .groupSearchBase("ou=groups")
                .contextSource(contextSource())
                .passwordCompare()
                    .passwordEncoder(new BCryptPasswordEncoder())
                    .passwordAttribute("userPassword");
    }
    private ContextSource contextSource() {
        LdapContextSource contextSource = new LdapContextSource();
        contextSource.setUrl("ldap://localhost:389");
        contextSource.setBase("dc=springframework,dc=org");
        contextSource.setUserDn("cn=admin,dc=springframework,dc=org");
        contextSource.setPassword("adminpassword");
        return contextSource;
    }
}

在上面的例子中,我們使用了“ldapAuthentication()”方法啟用了LDAP身份驗(yàn)證,并使用“userDnPatterns()”方法和“groupSearchBase()”方法定義了用戶和組的搜索路徑。然后,我們使用“contextSource()”方法定義了LDAP服務(wù)器的上下文源,包括LDAP服務(wù)器的URL、根目錄、管理員用戶名和密碼等。

CSRF防范

Spring Security提供了CSRF防范功能,可以防止跨站點(diǎn)請(qǐng)求偽造攻擊。我們可以通過(guò)“csrf()”方法開(kāi)啟CSRF防范:

@Configuration
@EnableWebSecurity
public class CsrfSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .and()
            .logout()
                .and()
            .csrf();
    }
}

在上面的例子中,我們使用了“csrf()”方法開(kāi)啟了CSRF防范。Spring Security默認(rèn)情況下將會(huì)在所有POST、PUT、DELETE等非GET請(qǐng)求中自動(dòng)包含CSRF令牌,以確保請(qǐng)求來(lái)自于合法的來(lái)源。

加密密碼

Spring Security提供了多種加密算法來(lái)加密密碼,包括BCrypt、SHA-256等。我們可以使用“PasswordEncoder”接口的實(shí)現(xiàn)類來(lái)進(jìn)行密碼加密和驗(yàn)證。示例代碼如下:

@Configuration
@EnableWebSecurity
public class PasswordEncoderSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .formLogin();
    }
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("admin").password(passwordEncoder().encode("admin123")).roles("ADMIN")
                .and()
                .withUser("user").password(passwordEncoder().encode("user123")).roles("USER");
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

在上面的例子中,我們使用了“PasswordEncoder”接口的實(shí)現(xiàn)類“BCryptPasswordEncoder”來(lái)進(jìn)行密碼加密和驗(yàn)證,并在“configureGlobal()”方法中使用“passwordEncoder()”方法對(duì)密碼進(jìn)行加密。這樣,在用戶認(rèn)證時(shí),Spring Security會(huì)自動(dòng)調(diào)用相應(yīng)的密碼加密算法對(duì)用戶輸入的密碼進(jìn)行加密和驗(yàn)證。

值得注意的是,在驗(yàn)證用戶密碼時(shí),我們應(yīng)該使用相應(yīng)的密碼加密算法來(lái)進(jìn)行驗(yàn)證,而不是使用明文比較。這樣可以保證密碼的安全性。

以上就是一文帶你掌握Spring Security框架的使用的詳細(xì)內(nèi)容,更多關(guān)于Spring Security框架的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java中的位運(yùn)算符、移位運(yùn)算詳細(xì)介紹

    Java中的位運(yùn)算符、移位運(yùn)算詳細(xì)介紹

    這篇文章主要介紹了Java中的位運(yùn)算符、移位運(yùn)算,有需要的朋友可以參考一下
    2013-12-12
  • Java中Integer類型值相等判斷方法

    Java中Integer類型值相等判斷方法

    這篇文章主要給大家介紹了關(guān)于Java中Integer類型值相等判斷的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Mybatis分步查詢的實(shí)現(xiàn)示例

    Mybatis分步查詢的實(shí)現(xiàn)示例

    本文主要介紹了Mybatis分步查詢的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • springbooot整合dynamic?datasource數(shù)據(jù)庫(kù)密碼加密方式

    springbooot整合dynamic?datasource數(shù)據(jù)庫(kù)密碼加密方式

    這篇文章主要介紹了springbooot整合dynamic?datasource?數(shù)據(jù)庫(kù)密碼加密方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • java 優(yōu)雅關(guān)閉線程池的方案

    java 優(yōu)雅關(guān)閉線程池的方案

    這篇文章主要介紹了java 優(yōu)雅關(guān)閉線程池的方案,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下
    2020-11-11
  • Java為何需要平衡方法調(diào)用與內(nèi)聯(lián)

    Java為何需要平衡方法調(diào)用與內(nèi)聯(lián)

    這篇文章主要介紹了Java為何需要平衡方法調(diào)用與內(nèi)聯(lián),幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2021-01-01
  • spring boot security自定義認(rèn)證的代碼示例

    spring boot security自定義認(rèn)證的代碼示例

    這篇文章主要介紹了spring boot security自定義認(rèn)證,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • spring boot實(shí)現(xiàn)過(guò)濾器和攔截器demo

    spring boot實(shí)現(xiàn)過(guò)濾器和攔截器demo

    本篇文章主要介紹了spring boot實(shí)現(xiàn)過(guò)濾器和攔截器demo ,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-02-02
  • Java字符串常量池示例詳解

    Java字符串常量池示例詳解

    作為最基礎(chǔ)的引用數(shù)據(jù)類型,Java設(shè)計(jì)者為 String 提供了字符串常量池以提高其性能,下面這篇文章主要給大家介紹了關(guān)于Java字符串常量池的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • Netty學(xué)習(xí)教程之基礎(chǔ)使用篇

    Netty學(xué)習(xí)教程之基礎(chǔ)使用篇

    Netty是由JBOSS提供的一個(gè)Java開(kāi)源框架。Netty提供異步的、事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用程序框架和工具,用以快速開(kāi)發(fā)高性能、高可靠性的網(wǎng)絡(luò)服務(wù)器和客戶端程序。下面這篇文章主要給大家介紹了關(guān)于Netty基礎(chǔ)使用的相關(guān)資料,需要的朋友可以參考下。
    2017-05-05

最新評(píng)論

团风县| 本溪市| 达孜县| 大悟县| 克拉玛依市| 文山县| 从江县| 子长县| 平远县| 驻马店市| 连平县| 长海县| 康定县| 大港区| 德州市| 曲周县| 夹江县| 渭源县| 呼图壁县| 城步| 金堂县| 昌黎县| 承德县| 安化县| 泌阳县| 富蕴县| 剑河县| 通州市| 五河县| 阳朔县| 铁岭市| 徐闻县| 漳浦县| 邢台市| 施秉县| 博罗县| 玉屏| 会昌县| 吉安县| 邳州市| 枣庄市|