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

java編程SpringSecurity入門(mén)原理及應(yīng)用簡(jiǎn)介

 更新時(shí)間:2021年09月27日 16:07:14   作者:不會(huì)編程的派大星  
Spring 是非常流行和成功的 Java 應(yīng)用開(kāi)發(fā)框架,Spring Security 正是 Spring 家族中的成員。Spring Security 基于 Spring 框架,提供了一套 Web 應(yīng)用安全性的完整解決方案

1. SpringSecurity 框架簡(jiǎn)介

1.1 概要

正如你可能知道的關(guān)于安全方面的兩個(gè)主要區(qū)域是“認(rèn)證”和“授權(quán)”(或者訪問(wèn)控制),一般來(lái)說(shuō),Web 應(yīng)用的安全性包括用戶(hù)認(rèn)證(Authentication)和用戶(hù)授權(quán)(Authorization)兩個(gè)部分,這兩點(diǎn)也是 Spring Security 重要核心功能。

(1) 用戶(hù)認(rèn)證指的是:驗(yàn)證某個(gè)用戶(hù)是否為系統(tǒng)中的合法主體,也就是說(shuō)用戶(hù)能否訪問(wèn)該系統(tǒng)。用戶(hù)認(rèn)證一般要求用戶(hù)提供用戶(hù)名和密碼。系統(tǒng)通過(guò)校驗(yàn)用戶(hù)名和密碼來(lái)完成認(rèn)證過(guò)程。通俗點(diǎn)說(shuō)就是系統(tǒng)認(rèn)為用戶(hù)是否能登錄

(2) 用戶(hù)授權(quán)指的是驗(yàn)證某個(gè)用戶(hù)是否有權(quán)限執(zhí)行某個(gè)操作。在一個(gè)系統(tǒng)中,不同用戶(hù)所具有的權(quán)限是不同的。比如對(duì)一個(gè)文件來(lái)說(shuō),有的用戶(hù)只能進(jìn)行讀取,而有的用戶(hù)可以進(jìn)行修改。一般來(lái)說(shuō),系統(tǒng)會(huì)為不同的用戶(hù)分配不同的角色,而每個(gè)角色則對(duì)應(yīng)一系列的權(quán)限。通俗點(diǎn)講就是系統(tǒng)判斷用戶(hù)是否有權(quán)限去做某些事情。

1.2 組成以及同款產(chǎn)品(shiro)對(duì)比

1.2.1 Spring Security

SpringSecurity 特點(diǎn):

  • 和 Spring 無(wú)縫整合。
  •  全面的權(quán)限控制。
  •  專(zhuān)門(mén)為Web 開(kāi)發(fā)而設(shè)計(jì)。
  • 舊版本不能脫離Web 環(huán)境使用。
  • 新版本對(duì)整個(gè)框架進(jìn)行了分層抽取,分成了核心模塊和Web 模塊。單獨(dú)引入核心模塊就可以脫離Web 環(huán)境。
  •  重量級(jí)。

1.2.2 Shiro

Apache 旗下的輕量級(jí)權(quán)限控制框架。

特點(diǎn):

  • 輕量級(jí)。Shiro 主張的理念是把復(fù)雜的事情變簡(jiǎn)單。針對(duì)對(duì)性能有更高要求的互聯(lián)網(wǎng)應(yīng)用有更好表現(xiàn)。
  • 通用性。

好處:不局限于Web 環(huán)境,可以脫離Web 環(huán)境使用。
缺陷:在Web 環(huán)境下一些特定的需求需要手動(dòng)編寫(xiě)代碼定制。

Spring Security 是 Spring 家族中的一個(gè)安全管理框架,實(shí)際上,在 Spring Boot 出現(xiàn)之前,Spring Security 就已經(jīng)發(fā)展了多年了,但是使用的并不多,安全管理這個(gè)領(lǐng)域,一直是 Shiro 的天下。

相對(duì)于 Shiro,在 SSM 中整合 Spring Security 都是比較麻煩的操作,所以,SpringSecurity 雖然功能比 Shiro 強(qiáng)大,但是使用反而沒(méi)有 Shiro 多(Shiro 雖然功能沒(méi)有Spring Security 多,但是對(duì)于大部分項(xiàng)目而言,Shiro 也夠用了)。

自從有了 Spring Boot 之后,Spring Boot 對(duì)于 Spring Security 提供了自動(dòng)化配置方案,可以使用更少的配置來(lái)使用 Spring Security。

因此,一般來(lái)說(shuō),常見(jiàn)的安全管理技術(shù)棧的組合是這樣的:

SSM + Shiro
Spring Boot/Spring Cloud + Spring Security

以上只是一個(gè)推薦的組合而已,如果單純從技術(shù)上來(lái)說(shuō),無(wú)論怎么組合,都是可以運(yùn)行的。

1.3 模塊劃分

在這里插入圖片描述

1.4 SpringSecurity 基本原理

SpringSecurity 本質(zhì)是一個(gè)過(guò)濾器鏈: 從啟動(dòng)是可以獲取到過(guò)濾器鏈:

在這里插入圖片描述

代碼底層流程:重點(diǎn)看三個(gè)過(guò)濾器:
FilterSecurityInterceptor:是一個(gè)方法級(jí)的權(quán)限過(guò)濾器, 基本位于過(guò)濾鏈的最底部。

1.5.UserDetailsService 接口講解

當(dāng)什么也沒(méi)有配置的時(shí)候,賬號(hào)和密碼是由 Spring Security 定義生成的。而在實(shí)際項(xiàng)目中
賬號(hào)和密碼都是從數(shù)據(jù)庫(kù)中查詢(xún)出來(lái)的。 所以我們要通過(guò)自定義邏輯控制認(rèn)證邏輯。
如果需要自定義邏輯時(shí),只需要實(shí)現(xiàn)userDetailsService接口即可,定義如下:

在這里插入圖片描述

2.SpringSecurity Web 權(quán)限方案

2.1設(shè)置登錄系統(tǒng)的賬號(hào)密碼(三種方式)

一:在application.xml中自行配置

spring.security.user.name = xxx
spring.security.user.password = xxx

二:編寫(xiě)類(lèi)實(shí)現(xiàn)接口

三:實(shí)現(xiàn)數(shù)據(jù)庫(kù)認(rèn)證來(lái)完成用戶(hù)登錄
這里就拿一個(gè)例子來(lái)完成認(rèn)證和授權(quán)

設(shè)計(jì)數(shù)據(jù)庫(kù)表

在這里插入圖片描述

建立springboot項(xiàng)目,勾選相應(yīng)依賴(lài)

在這里插入圖片描述

完整pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

數(shù)據(jù)庫(kù)配置

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    username: root
    password: xxxxxx
    url: jdbc:mysql://xxxxxxxxxx //根據(jù)自己情況填寫(xiě)
   

創(chuàng)建對(duì)應(yīng)的實(shí)體類(lèi)

package com.example.demo.domain;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class User implements UserDetails {
    private Integer id;
    private String username;
    private String password;
    private Boolean enabled;
    private Boolean locked;
    private List<Role> roles;
    @Override
    // 實(shí)體類(lèi)和SpringSecurity轉(zhuǎn)換
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        for (Role role : roles) {
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }
        return authorities;
    }
    @Override
    public String getPassword() {
        return null;
    }
    @Override
    public String getUsername() {
        return null;
    }
    @Override
    public boolean isAccountNonExpired() {
        return false;
    }
    @Override
    public boolean isAccountNonLocked() {
        return false;
    }
    @Override
    public boolean isCredentialsNonExpired() {
        return false;
    }
    @Override
    public boolean isEnabled() {
        return false;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public Boolean getEnabled() {
        return enabled;
    }
    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }
    public Boolean getLocked() {
        return locked;
    }
    public void setLocked(Boolean locked) {
        this.locked = locked;
    }
    public List<Role> getRoles() {
        return roles;
    }
    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }
}

package com.example.demo.domain;
public class Role {
    private Integer id;
    private String name;
    private String nameZh;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getNameZh() {
        return nameZh;
    }
    public void setNameZh(String nameZh) {
        this.nameZh = nameZh;
    }
}

創(chuàng)建service層

package com.example.demo.mapper;
import com.example.demo.domain.Role;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.graalvm.compiler.nodeinfo.StructuralInput;
import org.springframework.security.core.userdetails.User;
import java.util.List;
@Mapper
public interface UserMapper {
    @Select("select * from user where username=#{username}")
    public User loadUserByUsername(String username);
    @Select("select * from role r, user_role ur where r.id = ur.rid and ur.uid = #{id}")
    public List<Role> getUserRoleByUid(Integer id);
}

配置spring security

package com.example.demo.config;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configurable
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserService userService;
    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService);
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("admin")
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginProcessingUrl("/login").permitAll()
                .and()
                .csrf().disable();
    }
}


security配置類(lèi)說(shuō)明

在這里插入圖片描述

3.security-記住我-的實(shí)現(xiàn)

在security配置類(lèi)中開(kāi)啟remember me功能,并設(shè)置有效期。默認(rèn)時(shí)間為兩周。

在這里插入圖片描述

4.用戶(hù)注銷(xiāo)功能實(shí)現(xiàn)

通過(guò)退出按鈕找到映射地址,在配置類(lèi)中添加退出映射地址

在這里插入圖片描述

5.關(guān)于CSRF

跨站請(qǐng)求偽造(英語(yǔ):Cross-site request forgery),也被稱(chēng)為 one-click
attack 或者 session riding,通??s寫(xiě)為 CSRF 或者 XSRF, 是一種挾制用戶(hù)在當(dāng)前已登錄的 Web 應(yīng)用程序上執(zhí)行非本意的操作的攻擊方法。跟跨網(wǎng)站腳本(XSS)相比,XSS 利用的是用戶(hù)對(duì)指定網(wǎng)站的信任,CSRF 利用的是網(wǎng)站對(duì)用戶(hù)網(wǎng)頁(yè)瀏覽器的信任。

跨站請(qǐng)求攻擊,簡(jiǎn)單地說(shuō),是攻擊者通過(guò)一些技術(shù)手段欺騙用戶(hù)的瀏覽器去訪問(wèn)一個(gè)自己曾經(jīng)認(rèn)證過(guò)的網(wǎng)站并運(yùn)行一些操作(如發(fā)郵件,發(fā)消息,甚至財(cái)產(chǎn)操作如轉(zhuǎn)賬和購(gòu)買(mǎi)商品)。由于瀏覽器曾經(jīng)認(rèn)證過(guò),所以被訪問(wèn)的網(wǎng)站會(huì)認(rèn)為是真正的用戶(hù)操作而去運(yùn)行。這利用了web 中用戶(hù)身份驗(yàn)證的一個(gè)漏洞:簡(jiǎn)單的身份驗(yàn)證只能保證請(qǐng)求發(fā)自某個(gè)用戶(hù)的瀏覽器,卻不能保證請(qǐng)求本身是用戶(hù)自愿發(fā)出的。

從 Spring Security 4.0 開(kāi)始,默認(rèn)情況下會(huì)啟用CSRF 保護(hù),以防止CSRF 攻擊應(yīng)用程序,Spring Security CSRF 會(huì)針對(duì) PATCH,POST,PUT 和DELETE 方法進(jìn)行防護(hù)。

6.spring security原理總結(jié)

SpringSecurity 采用的是責(zé)任鏈的設(shè)計(jì)模式,它有一條很長(zhǎng)的過(guò)濾器鏈。

現(xiàn)在對(duì)這條過(guò)濾器鏈的 15 個(gè)過(guò)濾器進(jìn)行說(shuō)明:

(1) WebAsyncManagerIntegrationFilter:將 Security 上下文與 Spring Web 中用于處理異步請(qǐng)求映射的 WebAsyncManager 進(jìn)行集成。

(2) SecurityContextPersistenceFilter:在每次請(qǐng)求處理之前將該請(qǐng)求相關(guān)的安全上下文信息加載到 SecurityContextHolder 中,然后在該次請(qǐng)求處理完成之后,將
SecurityContextHolder 中關(guān)于這次請(qǐng)求的信息存儲(chǔ)到一個(gè)“倉(cāng)儲(chǔ)”中,然后將
SecurityContextHolder 中的信息清除,例如在 Session 中維護(hù)一個(gè)用戶(hù)的安全信息就是這個(gè)過(guò)濾器處理的。

(3) HeaderWriterFilter:用于將頭信息加入響應(yīng)中。

(4) CsrfFilter:用于處理跨站請(qǐng)求偽造。

(5) LogoutFilter:用于處理退出登錄。

(6) UsernamePasswordAuthenticationFilter:用于處理基于表單的登錄請(qǐng)求,從表單中獲取用戶(hù)名和密碼。默認(rèn)情況下處理來(lái)自 /login 的請(qǐng)求。從表單中獲取用戶(hù)名和密碼時(shí),默認(rèn)使用的表單 name 值為 username 和 password,這兩個(gè)值可以通過(guò)設(shè)置這個(gè)過(guò)濾器的 usernameParameter 和 passwordParameter 兩個(gè)參數(shù)的值進(jìn)行修改。

(7) DefaultLoginPageGeneratingFilter:如果沒(méi)有配置登錄頁(yè)面,那系統(tǒng)初始化時(shí)就會(huì)配置這個(gè)過(guò)濾器,并且用于在需要進(jìn)行登錄時(shí)生成一個(gè)登錄表單頁(yè)面。

(8) BasicAuthenticationFilter:檢測(cè)和處理 http basic 認(rèn)證。

(9) RequestCacheAwareFilter:用來(lái)處理請(qǐng)求的緩存。

(10) SecurityContextHolderAwareRequestFilter:主要是包裝請(qǐng)求對(duì)象 request。

(11) AnonymousAuthenticationFilter:檢測(cè) SecurityContextHolder 中是否存在
Authentication 對(duì)象,如果不存在為其提供一個(gè)匿名 Authentication。

(12) SessionManagementFilter:管理 session 的過(guò)濾器

(13) ExceptionTranslationFilter:處理 AccessDeniedException 和
AuthenticationException 異常。

(14) FilterSecurityInterceptor:可以看做過(guò)濾器鏈的出口。

(15) RememberMeAuthenticationFilter:當(dāng)用戶(hù)沒(méi)有登錄而直接訪問(wèn)資源時(shí), 從 cookie 里找出用戶(hù)的信息, 如果 Spring Security 能夠識(shí)別出用戶(hù)提供的 remember me cookie, 用戶(hù)將不必填寫(xiě)用戶(hù)名和密碼, 而是直接登錄進(jìn)入系統(tǒng),該過(guò)濾器默認(rèn)不開(kāi)啟。

以上就是java編程入門(mén)SpringSecurity原理及應(yīng)用簡(jiǎn)介的詳細(xì)內(nèi)容,更多關(guān)于java編程SpringSecurity簡(jiǎn)介的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • mybatis防止SQL注入的方法實(shí)例詳解

    mybatis防止SQL注入的方法實(shí)例詳解

    SQL注入是一種很簡(jiǎn)單的攻擊手段,但直到今天仍然十分常見(jiàn)。那么mybatis是如何防止SQL注入的呢?下面腳本之家小編給大家?guī)?lái)了實(shí)例代碼,需要的朋友參考下吧
    2018-04-04
  • 23種設(shè)計(jì)模式(21)java享元模式

    23種設(shè)計(jì)模式(21)java享元模式

    這篇文章主要為大家詳細(xì)介紹了23種設(shè)計(jì)模式之java享元模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • springcloud-gateway集成knife4j的示例詳解

    springcloud-gateway集成knife4j的示例詳解

    這篇文章主要介紹了springcloud-gateway集成knife4j的示例詳解,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • Maven Optional依賴(lài)屬性的含義及妙用

    Maven Optional依賴(lài)屬性的含義及妙用

    這篇文章主要為大家介紹了Maven Optional依賴(lài)屬性的含義及妙用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • SpringBoot解決跨域問(wèn)題小結(jié)

    SpringBoot解決跨域問(wèn)題小結(jié)

    在現(xiàn)代Web應(yīng)用中,由于安全性和隱私的考慮,瀏覽器限制了從一個(gè)域向另一個(gè)域發(fā)起的跨域HTTP請(qǐng)求,Spring?Boot提供了多種方式來(lái)處理跨域請(qǐng)求,本文將介紹其中的幾種方法,感興趣的朋友一起看看吧
    2023-12-12
  • 詳解如何使用java實(shí)現(xiàn)Open Addressing

    詳解如何使用java實(shí)現(xiàn)Open Addressing

    這篇文章主要介紹了詳解如何使用java實(shí)現(xiàn)Open Addressing,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • MyBatis框架關(guān)聯(lián)映射實(shí)例詳解

    MyBatis框架關(guān)聯(lián)映射實(shí)例詳解

    這篇文章主要介紹了MyBatis框架關(guān)聯(lián)映射,關(guān)系映射主要處理復(fù)雜的SQl查詢(xún),如子查詢(xún),多表聯(lián)查等復(fù)雜查詢(xún),應(yīng)用此種需求時(shí)可以考慮使用,需要的朋友可以參考下
    2022-11-11
  • 基于java TCP網(wǎng)絡(luò)通信的實(shí)例詳解

    基于java TCP網(wǎng)絡(luò)通信的實(shí)例詳解

    本篇文章是對(duì)java中TCP網(wǎng)絡(luò)通信的實(shí)例進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • Java?數(shù)據(jù)結(jié)構(gòu)與算法系列精講之單向鏈表

    Java?數(shù)據(jù)結(jié)構(gòu)與算法系列精講之單向鏈表

    單向鏈表特點(diǎn)是鏈表的鏈接方向是單向的,訪問(wèn)要通過(guò)順序讀取從頭部開(kāi)始。鏈表是使用指針構(gòu)造的列表,是由一個(gè)個(gè)結(jié)點(diǎn)組裝起來(lái)的,又稱(chēng)為結(jié)點(diǎn)列表。其中每個(gè)結(jié)點(diǎn)都有指針成員變量指向列表中的下一個(gè)結(jié)點(diǎn),head指針指向第一個(gè)結(jié)點(diǎn)稱(chēng)為表頭,而終止于最后一個(gè)指向nuLL的指針
    2022-02-02
  • SpringBoot使用Jsp的示例代碼

    SpringBoot使用Jsp的示例代碼

    這篇文章主要介紹了SpringBoot使用Jsp的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08

最新評(píng)論

武乡县| 子洲县| 天镇县| 盐城市| 长葛市| 扶沟县| 桓台县| 牡丹江市| 濮阳市| 山丹县| 江门市| 玉溪市| 扶沟县| 松原市| 卓尼县| 滦南县| 个旧市| 郯城县| 富宁县| 济阳县| 汉沽区| 西充县| 阿城市| 元谋县| 桐城市| 名山县| 海林市| 嘉禾县| 石柱| 偃师市| 延边| 望谟县| 和平区| 横峰县| 余庆县| 海城市| 微山县| 万荣县| 宿松县| 卫辉市| 正宁县|