日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring boot+Spring Security 4配置整合实例

發(fā)布時間:2024/4/14 javascript 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring boot+Spring Security 4配置整合实例 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本例所覆蓋的內(nèi)容:

1.?使用Spring Security管理用戶身份認(rèn)證、登錄退出

2.?用戶密碼加密及驗證

3.?采用數(shù)據(jù)庫的方式實現(xiàn)Spring Securityremember-me功能

4.?獲取登錄用戶信息。

5.使用Spring Security管理url和權(quán)限

?

本例所使用的框架:

1.?Spring boot

2.?Spring MVC

3.?Spring Security

4.?Spring Data JPA

5.?thymeleaf

6.gradle

一、?整合Spring Security

build.gradle中加入如下片段:

[plain] view plaincopyprint?
  • ??
  • [plain] view plain copy print?
  • compile('org.springframework.boot:spring-boot-starter-data-jpa')??
  • compile("org.springframework.boot:spring-boot-starter-thymeleaf")??
  • compile("org.springframework.boot:spring-boot-starter-security")<u>??
  • ????testCompile("org.springframework.boot:spring-boot-starter-test")??
  • testCompile("org.springframework.security:spring-security-test")??
  • compile('org.springframework.boot:spring-boot-starter-data-jpa')compile("org.springframework.boot:spring-boot-starter-thymeleaf")compile("org.springframework.boot:spring-boot-starter-security") testCompile("org.springframework.boot:spring-boot-starter-test")testCompile("org.springframework.security:spring-security-test")

    使用Spring Security4的四種方法概述

    ????那么在Spring Security4的使用中,有4種方法:

  • ? ? 一種是全部利用配置文件,將用戶、權(quán)限、資源(url)硬編碼在xml文件中;
  • ? ? 二種是用戶和權(quán)限用數(shù)據(jù)庫存儲,而資源(url)和權(quán)限的對應(yīng)采用硬編碼配置。
  • ? ? 三種是細(xì)分角色和權(quán)限,并將用戶、角色、權(quán)限和資源均采用數(shù)據(jù)庫存儲,并且自定義過濾器,代替原有的FilterSecurityInterceptor過濾器 ? ? ? ? 并分別實現(xiàn)AccessDecisionManager、InvocationSecurityMetadataSourceService和UserDetailsService,并在配置文件中進(jìn)行相應(yīng)配置。
  • ? ? 四是修改spring security的源代碼,主要是修改InvocationSecurityMetadataSourceService和UserDetailsService兩個類。 前者是將配置文件 ? ? 或數(shù)據(jù)庫中存儲的資源(url)提取出來加工成為url和權(quán)限列表的Map供Security使用,后者提取用戶名和權(quán)限組成一個完整的(UserDetails)User ? ? 對象,該對象可以提供用戶的詳細(xì)信息供AuthentationManager進(jìn)行認(rèn)證與授權(quán)使用。
  • 我們今天來實現(xiàn)一下第三種。

    ?當(dāng)然,spring security4畢竟是西方國家的東西,以英文為主,使用習(xí)慣和文化的差異共存,況且為了適應(yīng)大多數(shù)Web應(yīng)用的權(quán)限管理,作者將Spring Security4打造的精簡而靈活。精簡指Spring Security4對用戶和權(quán)限的表設(shè)計的非常簡單,并且沒有采用數(shù)據(jù)庫來管理資源(URL)。這樣的話,對于我們國人用戶來說,是個很大的遺憾,這個遺憾甚至能夠影響到我們對安全框架的選型。你想啊,在國內(nèi)大多數(shù)項目中,均設(shè)置了比較復(fù)雜的權(quán)限控制,一般就會涉及到用戶、角色、資源3張表,若要加上3張表之間的對應(yīng)關(guān)系表2張,得有5張表。

    ? ? 但是,Spring Security4提供了靈活的擴(kuò)展方法。具體應(yīng)該擴(kuò)展哪些類呢? 或者到底Spring Security3工作的流程如何,你不妨參看下面一篇文章,就會獲得
    一些啟示,網(wǎng)址為:http://www.blogjava.net/SpartaYew/archive/2011/06/15/350630.html, 哈哈,謝謝分享。

    還有一個地址很有價值,http://download.csdn.net/detail/muddled/8981809,我就參考著上面的介紹擴(kuò)展了4個類。

    首先來說一下第三種方法的實現(xiàn)流程,我畫了一張簡易版流程圖,幫助大家理解spring security4 的工作機(jī)制:


    下面我們就來根據(jù)這個圖中標(biāo)注出的,重要的幾個4個類來配置吧!

  • 當(dāng)然要現(xiàn)在application.properties配置文件中配置好數(shù)據(jù)庫。
  • 開始配置相關(guān)的實體類 SysUser.java ?SRole.java ?SysResource.java?SysResourceRole.java
  • [java] view plaincopyprint?
  • package?security.entity;??
  • ??
  • import?java.util.Date;??
  • import?java.util.HashSet;??
  • import?java.util.Set;??
  • ??
  • import?javax.persistence.Column;??
  • import?javax.persistence.Entity;??
  • import?javax.persistence.FetchType;??
  • import?javax.persistence.GeneratedValue;??
  • import?javax.persistence.GenerationType;??
  • import?javax.persistence.Id;??
  • import?javax.persistence.OneToMany;??
  • import?javax.persistence.Table;??
  • import?javax.persistence.Temporal;??
  • import?javax.persistence.TemporalType;??
  • ????@Entity??
  • ????@Table(name?=?"s_user")//code11??
  • ????public?class?SysUser?implements?java.io.Serializable?{??
  • ??????????
  • ????????@Id??
  • ????????@GeneratedValue(strategy?=?GenerationType.IDENTITY)??
  • ????????@Column(name?=?"id",?unique?=?true,?nullable?=?false)??
  • ????????private?Integer?id;??
  • ????????@Column(name?=?"name",?length?=?120)??
  • ????????private?String?name;?//用戶名??
  • ????????@Column(name?=?"email",?length?=?50)??
  • ????????private?String?email;//用戶郵箱??
  • ????????@Column(name?=?"password",?length?=?120)??
  • ????????private?String?password;//用戶密碼??
  • ????????@Temporal(TemporalType.DATE)??
  • ????????@Column(name?=?"dob",?length?=?10)??
  • ????????private?Date?dob;//時間??
  • ??????????
  • ????????@OneToMany(fetch?=?FetchType.EAGER,?mappedBy?=?"SUser")??
  • ????????private?Set<SysRole>?SysRoles?=?new?HashSet<SysRole>(0);//?所對應(yīng)的角色集合??
  • ??
  • ????????public?SysUser()?{??
  • ????????}??
  • ??
  • ????????public?SysUser(String?name,?String?email,?String?password,?Date?dob,?Set<SysRole>?SysRoles)?{??
  • ????????????this.name?=?name;??
  • ????????????this.email?=?email;??
  • ????????????this.password?=?password;??
  • ????????????this.dob?=?dob;??
  • ????????????this.SysRoles?=?SysRoles;??
  • ????????}??
  • ??
  • ??????????
  • ????????public?Integer?getId()?{??
  • ????????????return?this.id;??
  • ????????}??
  • ??
  • ????????public?void?setId(Integer?id)?{??
  • ????????????this.id?=?id;??
  • ????????}??
  • ??
  • ??????????
  • ????????public?String?getName()?{??
  • ????????????return?this.name;??
  • ????????}??
  • ??
  • ????????public?void?setName(String?name)?{??
  • ????????????this.name?=?name;??
  • ????????}??
  • ??
  • ????????public?String?getEmail()?{??
  • ????????????return?this.email;??
  • ????????}??
  • ??
  • ????????public?void?setEmail(String?email)?{??
  • ????????????this.email?=?email;??
  • ????????}??
  • ??
  • ????????public?String?getPassword()?{??
  • ????????????return?this.password;??
  • ????????}??
  • ??
  • ????????public?void?setPassword(String?password)?{??
  • ????????????this.password?=?password;??
  • ????????}??
  • ??
  • ??????????
  • ????????public?Date?getDob()?{??
  • ????????????return?this.dob;??
  • ????????}??
  • ??
  • ????????public?void?setDob(Date?dob)?{??
  • ????????????this.dob?=?dob;??
  • ????????}??
  • ??
  • ????????@OneToMany(fetch?=?FetchType.EAGER,?mappedBy?=?"SUser")??
  • ????????public?Set<SysRole>?getSysRoles()?{??
  • ????????????return?this.SysRoles;??
  • ????????}??
  • ??
  • ????????public?void?setSRoles(Set<SysRole>?SysRoles)?{??
  • ????????????this.SysRoles?=?SysRoles;??
  • ????????}??
  • ??
  • }??
  • package security.entity;import java.util.Date; import java.util.HashSet; import java.util.Set;import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType;@Entity@Table(name = "s_user")//code11public class SysUser implements java.io.Serializable {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id", unique = true, nullable = false)private Integer id;@Column(name = "name", length = 120)private String name; //用戶名@Column(name = "email", length = 50)private String email;//用戶郵箱@Column(name = "password", length = 120)private String password;//用戶密碼@Temporal(TemporalType.DATE)@Column(name = "dob", length = 10)private Date dob;//時間@OneToMany(fetch = FetchType.EAGER, mappedBy = "SUser")private Set<SysRole> SysRoles = new HashSet<SysRole>(0);// 所對應(yīng)的角色集合public SysUser() {}public SysUser(String name, String email, String password, Date dob, Set<SysRole> SysRoles) {this.name = name;this.email = email;this.password = password;this.dob = dob;this.SysRoles = SysRoles;}public Integer getId() {return this.id;}public void setId(Integer id) {this.id = id;}public String getName() {return this.name;}public void setName(String name) {this.name = name;}public String getEmail() {return this.email;}public void setEmail(String email) {this.email = email;}public String getPassword() {return this.password;}public void setPassword(String password) {this.password = password;}public Date getDob() {return this.dob;}public void setDob(Date dob) {this.dob = dob;}@OneToMany(fetch = FetchType.EAGER, mappedBy = "SUser")public Set<SysRole> getSysRoles() {return this.SysRoles;}public void setSRoles(Set<SysRole> SysRoles) {this.SysRoles = SysRoles;}}
    [java] view plaincopyprint?
  • package?security.entity;??
  • ??
  • import?java.util.Date;??
  • ??
  • import?javax.persistence.Column;??
  • import?javax.persistence.Entity;??
  • import?javax.persistence.FetchType;??
  • import?javax.persistence.GeneratedValue;??
  • import?javax.persistence.GenerationType;??
  • import?javax.persistence.Id;??
  • import?javax.persistence.JoinColumn;??
  • import?javax.persistence.ManyToOne;??
  • import?javax.persistence.Table;??
  • //角色表??
  • @Entity??
  • @Table(name="s_role")??
  • public?class?SysRole?{??
  • ????@Id??
  • ????@GeneratedValue(strategy=GenerationType.IDENTITY)??
  • ????@Column?(name="id",length=10)??
  • ????private?int?id;??
  • ??????
  • ????@ManyToOne(fetch?=?FetchType.LAZY)??
  • ????@JoinColumn(name?=?"uid",?nullable?=?false)??
  • ????private?SysUser?SUser;//角色對應(yīng)的用戶實體??
  • ??????
  • ????@Column(name="name",length=100)??
  • ????private?String?name;//角色名稱??
  • ??????
  • ????public?int?getId()?{??
  • ????????return?id;??
  • ????}??
  • ????public?void?setId(int?id)?{??
  • ????????this.id?=?id;??
  • ????}??
  • ??????
  • ????public?String?getName()?{??
  • ????????return?name;??
  • ????}??
  • ????public?void?setName(String?name)?{??
  • ????????this.name?=?name;??
  • ????}??
  • ????public?SysUser?getSUser()?{??
  • ????????return?SUser;??
  • ????}??
  • ????public?void?setSUser(SysUser?sUser)?{??
  • ????????SUser?=?sUser;??
  • ????}??
  • ??????
  • ??????
  • }??
  • package security.entity;import java.util.Date;import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; //角色表 @Entity @Table(name="s_role") public class SysRole {@Id@GeneratedValue(strategy=GenerationType.IDENTITY)@Column (name="id",length=10)private int id;@ManyToOne(fetch = FetchType.LAZY)@JoinColumn(name = "uid", nullable = false)private SysUser SUser;//角色對應(yīng)的用戶實體@Column(name="name",length=100)private String name;//角色名稱public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public SysUser getSUser() {return SUser;}public void setSUser(SysUser sUser) {SUser = sUser;}}
    [java] view plaincopyprint?
  • package?cn.paybay.ticketManager.entity;??
  • ??
  • import?javax.persistence.Column;??
  • import?javax.persistence.Entity;??
  • import?javax.persistence.GeneratedValue;??
  • import?javax.persistence.GenerationType;??
  • import?javax.persistence.Id;??
  • import?javax.persistence.Table;??
  • @Entity??
  • @Table(name="s_resource")??
  • public?class?SysResource?{??
  • ????????@Id??
  • ????????@GeneratedValue(strategy=GenerationType.IDENTITY)??
  • ????????@Column?(name="id",length=10)??
  • ????????private?int?id;??
  • ??????????
  • ????????@Column(name="resourceString",length=1000)??
  • ????????private?String?resourceString;//url??
  • ??????????
  • ????????@Column(name="resourceId",length=50)??
  • ????????private?String?resourceId;//資源ID??
  • ??????????
  • ????????@Column(name="remark",length=200)??
  • ????????private?String?remark;//備注??
  • ??????????
  • ????????@Column(name="resourceName",length=400)??
  • ????????private?String?resourceName;//資源名稱??
  • ??????????
  • ????????@Column(name="methodName",length=400)??
  • ????????private?String?methodName;//資源所對應(yīng)的方法名??
  • ??????????
  • ????????@Column(name="methodPath",length=1000)??
  • ????????private?String?methodPath;//資源所對應(yīng)的包路徑??
  • ??????????
  • ????????public?int?getId()?{??
  • ????????????return?id;??
  • ????????}??
  • ??
  • ????????public?void?setId(int?id)?{??
  • ????????????this.id?=?id;??
  • ????????}??
  • ??
  • ????????public?String?getResourceString()?{??
  • ????????????return?resourceString;??
  • ????????}??
  • ??
  • ????????public?void?setResourceString(String?resourceString)?{??
  • ????????????this.resourceString?=?resourceString;??
  • ????????}??
  • ??
  • ????????public?String?getResourceId()?{??
  • ????????????return?resourceId;??
  • ????????}??
  • ??
  • ????????public?void?setResourceId(String?resourceId)?{??
  • ????????????this.resourceId?=?resourceId;??
  • ????????}??
  • ??
  • ????????public?String?getRemark()?{??
  • ????????????return?remark;??
  • ????????}??
  • ??
  • ????????public?void?setRemark(String?remark)?{??
  • ????????????this.remark?=?remark;??
  • ????????}??
  • ??
  • ????????public?String?getResourceName()?{??
  • ????????????return?resourceName;??
  • ????????}??
  • ??
  • ????????public?void?setResourceName(String?resourceName)?{??
  • ????????????this.resourceName?=?resourceName;??
  • ????????}??
  • ??
  • ????????public?String?getMethodName()?{??
  • ????????????return?methodName;??
  • ????????}??
  • ??
  • ????????public?void?setMethodName(String?methodName)?{??
  • ????????????this.methodName?=?methodName;??
  • ????????}??
  • ??
  • ????????public?String?getMethodPath()?{??
  • ????????????return?methodPath;??
  • ????????}??
  • ??
  • ????????public?void?setMethodPath(String?methodPath)?{??
  • ????????????this.methodPath?=?methodPath;??
  • ????????}??
  • ??????????
  • ??????????
  • }??
  • package cn.paybay.ticketManager.entity;import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="s_resource") public class SysResource {@Id@GeneratedValue(strategy=GenerationType.IDENTITY)@Column (name="id",length=10)private int id;@Column(name="resourceString",length=1000)private String resourceString;//url@Column(name="resourceId",length=50)private String resourceId;//資源ID@Column(name="remark",length=200)private String remark;//備注@Column(name="resourceName",length=400)private String resourceName;//資源名稱@Column(name="methodName",length=400)private String methodName;//資源所對應(yīng)的方法名@Column(name="methodPath",length=1000)private String methodPath;//資源所對應(yīng)的包路徑public int getId() {return id;}public void setId(int id) {this.id = id;}public String getResourceString() {return resourceString;}public void setResourceString(String resourceString) {this.resourceString = resourceString;}public String getResourceId() {return resourceId;}public void setResourceId(String resourceId) {this.resourceId = resourceId;}public String getRemark() {return remark;}public void setRemark(String remark) {this.remark = remark;}public String getResourceName() {return resourceName;}public void setResourceName(String resourceName) {this.resourceName = resourceName;}public String getMethodName() {return methodName;}public void setMethodName(String methodName) {this.methodName = methodName;}public String getMethodPath() {return methodPath;}public void setMethodPath(String methodPath) {this.methodPath = methodPath;}}
    [java] view plaincopyprint?
  • package?security.entity;??
  • ??
  • import?java.util.Date;??
  • ??
  • import?javax.persistence.Column;??
  • import?javax.persistence.Entity;??
  • import?javax.persistence.FetchType;??
  • import?javax.persistence.GeneratedValue;??
  • import?javax.persistence.GenerationType;??
  • import?javax.persistence.Id;??
  • import?javax.persistence.JoinColumn;??
  • import?javax.persistence.ManyToOne;??
  • import?javax.persistence.Table;??
  • @Entity??
  • @Table(name="s_resource_role")??
  • public?class?SysResourceRole?{??
  • ????????@Id??
  • ????????@GeneratedValue(strategy=GenerationType.IDENTITY)??
  • ????????@Column?(name="id",length=10)??
  • ????????private?int?id;??
  • ??????????
  • ????????@Column(name="roleId",length=50)??
  • ????????private?String?roleId;?//角色I(xiàn)D??
  • ??????????
  • ????????@Column(name="resourceId",length=50)??
  • ????????private?String?resourceId;//資源ID??
  • ??????????
  • ????????@Column(name="updateTime")??
  • ????????private?Date?updateTime;//更新時間??
  • ??
  • ????????public?int?getId()?{??
  • ????????????return?id;??
  • ????????}??
  • ??
  • ????????public?void?setId(int?id)?{??
  • ????????????this.id?=?id;??
  • ????????}??
  • ??
  • ????????public?String?getRoleId()?{??
  • ????????????return?roleId;??
  • ????????}??
  • ??
  • ????????public?void?setRoleId(String?roleId)?{??
  • ????????????this.roleId?=?roleId;??
  • ????????}??
  • ??
  • ????????public?String?getResourceId()?{??
  • ????????????return?resourceId;??
  • ????????}??
  • ??
  • ????????public?void?setResourceId(String?resourceId)?{??
  • ????????????this.resourceId?=?resourceId;??
  • ????????}??
  • ??
  • ????????public?Date?getUpdateTime()?{??
  • ????????????return?updateTime;??
  • ????????}??
  • ??
  • ????????public?void?setUpdateTime(Date?updateTime)?{??
  • ????????????this.updateTime?=?updateTime;??
  • ????????}??
  • ??
  • ??????????
  • }??
  • package security.entity;import java.util.Date;import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; @Entity @Table(name="s_resource_role") public class SysResourceRole {@Id@GeneratedValue(strategy=GenerationType.IDENTITY)@Column (name="id",length=10)private int id;@Column(name="roleId",length=50)private String roleId; //角色I(xiàn)D@Column(name="resourceId",length=50)private String resourceId;//資源ID@Column(name="updateTime")private Date updateTime;//更新時間public int getId() {return id;}public void setId(int id) {this.id = id;}public String getRoleId() {return roleId;}public void setRoleId(String roleId) {this.roleId = roleId;}public String getResourceId() {return resourceId;}public void setResourceId(String resourceId) {this.resourceId = resourceId;}public Date getUpdateTime() {return updateTime;}public void setUpdateTime(Date updateTime) {this.updateTime = updateTime;}}
    好了實體類都建好了。然后運(yùn)行一下,springboot程序。hibernate會自動創(chuàng)建表。在表中插入幾條測試數(shù)據(jù):
  • s_user表
  • s_role表

  • ? ? ?6.s_resource表


    ? ? ? 7.s_resource_role表


    [sql] view plaincopyprint?
  • <span?style="color:rgb(51,204,0);">//請勿手工寫入數(shù)據(jù)?供remember-me功能使用</span>??
  • CREATE?TABLE?`persistent_logins`?(??
  • ??`username`?varchar(64)?NOT?NULL,??
  • ??`series`?varchar(64)?NOT?NULL,??
  • ??`token`?varchar(64)?NOT?NULL,??
  • ??`last_used`?timestamp?NOT?NULL?DEFAULT?CURRENT_TIMESTAMP?ON?UPDATE?CURRENT_TIMESTAMP,??
  • ??PRIMARY?KEY?(`series`)??
  • )??
  • //請勿手工寫入數(shù)據(jù) 供remember-me功能使用 CREATE TABLE `persistent_logins` (`username` varchar(64) NOT NULL,`series` varchar(64) NOT NULL,`token` varchar(64) NOT NULL,`last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`series`) )

    好了,現(xiàn)在我們來配置一下用戶和角色的認(rèn)證吧。

    1、首先,創(chuàng)建WebSecurityConfig.java配置類,其中不明所以的地方請參照上面的圖,慢慢往下看。

    [java] view plaincopyprint?
  • package?security;??
  • ??
  • import?org.springframework.beans.factory.annotation.Autowired;??
  • import?org.springframework.context.annotation.Bean;??
  • import?org.springframework.context.annotation.Configuration;??
  • 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.EnableWebSecurity;??
  • import?org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;??
  • import?org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;??
  • import?org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;??
  • ??
  • import?security.support.CustomUserDetailsService;??
  • import?security.support.LoginSuccessHandler;??
  • @Configuration??
  • @EnableWebSecurity??
  • public?class?WebSecurityConfig?extends?WebSecurityConfigurerAdapter?{??
  • ????@Autowired??
  • ????private?CustomUserDetailsService?customUserDetailsService;??
  • ????//http://localhost:8080/login?輸入正確的用戶名密碼?并且選中remember-me?則登陸成功,轉(zhuǎn)到?index頁面???
  • ????//再次訪問index頁面無需登錄直接訪問??
  • ????//訪問http://localhost:8080/home?不攔截,直接訪問,??
  • ????//訪問http://localhost:8080/hello?需要登錄驗證后,且具備?“ADMIN”權(quán)限hasAuthority("ADMIN")才可以訪問??
  • ????@Override??
  • ????protected?void?configure(HttpSecurity?http)?throws?Exception?{??
  • ????????http??
  • ????????.authorizeRequests()??
  • ????????.antMatchers("/home").permitAll()//訪問:/home?無需登錄認(rèn)證權(quán)限??
  • ????????.anyRequest().authenticated()?//其他所有資源都需要認(rèn)證,登陸后訪問??
  • ????????.antMatchers("/hello").hasAuthority("ADMIN")?//登陸后之后擁有“ADMIN”權(quán)限才可以訪問/hello方法,否則系統(tǒng)會出現(xiàn)“403”權(quán)限不足的提示??
  • ????????.and()??
  • ????????.formLogin()??
  • ????????.loginPage("/login")//指定登錄頁是”/login”??
  • ????????.permitAll()??
  • ????????.successHandler(loginSuccessHandler())?//登錄成功后可使用loginSuccessHandler()存儲用戶信息,可選。??
  • ????????.and()??
  • ????????.logout()??
  • ????????.logoutSuccessUrl("/home")?//退出登錄后的默認(rèn)網(wǎng)址是”/home”??
  • ????????.permitAll()??
  • ????????.invalidateHttpSession(true)??
  • ????????.and()??
  • ????????.rememberMe()//登錄后記住用戶,下次自動登錄,數(shù)據(jù)庫中必須存在名為persistent_logins的表??
  • ????????.tokenValiditySeconds(1209600);??
  • ????}??
  • ??
  • ????@Autowired??
  • ????public?void?configureGlobal(AuthenticationManagerBuilder?auth)?throws?Exception?{?????
  • //指定密碼加密所使用的加密器為passwordEncoder()??
  • //需要將密碼加密后寫入數(shù)據(jù)庫???
  • ????auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());??
  • ????????auth.eraseCredentials(false);?????????
  • ????}??
  • ??
  • ????@Bean??
  • ????public?BCryptPasswordEncoder?passwordEncoder()?{??
  • ????????return?new?BCryptPasswordEncoder(4);??
  • ????}??
  • ??
  • ????@Bean??
  • ????public?LoginSuccessHandler?loginSuccessHandler(){??
  • ????????return?new?LoginSuccessHandler();??
  • ????}??
  • }??
  • package security;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import security.support.CustomUserDetailsService; import security.support.LoginSuccessHandler; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate CustomUserDetailsService customUserDetailsService;//http://localhost:8080/login 輸入正確的用戶名密碼 并且選中remember-me 則登陸成功,轉(zhuǎn)到 index頁面 //再次訪問index頁面無需登錄直接訪問//訪問http://localhost:8080/home 不攔截,直接訪問,//訪問http://localhost:8080/hello 需要登錄驗證后,且具備 “ADMIN”權(quán)限hasAuthority("ADMIN")才可以訪問@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/home").permitAll()//訪問:/home 無需登錄認(rèn)證權(quán)限.anyRequest().authenticated() //其他所有資源都需要認(rèn)證,登陸后訪問.antMatchers("/hello").hasAuthority("ADMIN") //登陸后之后擁有“ADMIN”權(quán)限才可以訪問/hello方法,否則系統(tǒng)會出現(xiàn)“403”權(quán)限不足的提示.and().formLogin().loginPage("/login")//指定登錄頁是”/login”.permitAll().successHandler(loginSuccessHandler()) //登錄成功后可使用loginSuccessHandler()存儲用戶信息,可選。.and().logout().logoutSuccessUrl("/home") //退出登錄后的默認(rèn)網(wǎng)址是”/home”.permitAll().invalidateHttpSession(true).and().rememberMe()//登錄后記住用戶,下次自動登錄,數(shù)據(jù)庫中必須存在名為persistent_logins的表.tokenValiditySeconds(1209600);}@Autowiredpublic void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { //指定密碼加密所使用的加密器為passwordEncoder() //需要將密碼加密后寫入數(shù)據(jù)庫 auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());auth.eraseCredentials(false); }@Beanpublic BCryptPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder(4);}@Beanpublic LoginSuccessHandler loginSuccessHandler(){return new LoginSuccessHandler();} }
    2、CustomUserDetailsService.java

    [java] view plaincopyprint?
  • package?security.support;??
  • ??
  • import?org.springframework.beans.factory.annotation.Autowired;??
  • import?org.springframework.security.core.userdetails.UserDetails;??
  • import?org.springframework.security.core.userdetails.UserDetailsService;??
  • import?org.springframework.security.core.userdetails.UsernameNotFoundException;??
  • import?org.springframework.stereotype.Component;??
  • ??
  • import?security.entity.SysUser;??
  • import?security.entity.User;??
  • import?security.service.UserService;??
  • @Component??
  • public?class?CustomUserDetailsService?implements?UserDetailsService?{??
  • ????@Autowired??//業(yè)務(wù)服務(wù)類??
  • ????private?UserService?userService;??
  • ??
  • ????@Override??
  • ????public?UserDetails?loadUserByUsername(String?userName)?throws?UsernameNotFoundException?{??
  • ????????//SysUser對應(yīng)數(shù)據(jù)庫中的用戶表,是最終存儲用戶和密碼的表,可自定義??
  • ????????//本例使用SysUser中的name作為用戶名:??
  • ????????SysUser?user?=?userService.findByName(userName);??
  • ????????if?(user?==?null)?{??
  • ????????????throw?new?UsernameNotFoundException("UserName?"?+?userName?+?"?not?found");??
  • ????????}??
  • ????????//?SecurityUser實現(xiàn)UserDetails并將SysUser的name映射為username??
  • ????????SecurityUser?seu?=?new?SecurityUser(user);??
  • ????????return??seu;??
  • ????}??
  • ??
  • }??
  • package security.support;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component;import security.entity.SysUser; import security.entity.User; import security.service.UserService; @Component public class CustomUserDetailsService implements UserDetailsService {@Autowired //業(yè)務(wù)服務(wù)類private UserService userService;@Overridepublic UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {//SysUser對應(yīng)數(shù)據(jù)庫中的用戶表,是最終存儲用戶和密碼的表,可自定義//本例使用SysUser中的name作為用戶名:SysUser user = userService.findByName(userName);if (user == null) {throw new UsernameNotFoundException("UserName " + userName + " not found");}// SecurityUser實現(xiàn)UserDetails并將SysUser的name映射為usernameSecurityUser seu = new SecurityUser(user);return seu;}}
    3、SecurityUser.java

    [java] view plaincopyprint?
  • package?security.support;??
  • ??
  • import?java.util.ArrayList;??
  • import?java.util.Collection;??
  • import?java.util.HashSet;??
  • import?java.util.List;??
  • import?java.util.Set;??
  • ??
  • import?org.springframework.beans.factory.annotation.Autowired;??
  • import?org.springframework.security.core.GrantedAuthority;??
  • import?org.springframework.security.core.authority.SimpleGrantedAuthority;??
  • import?org.springframework.security.core.userdetails.UserDetails;??
  • ??
  • import?security.entity.SysRole<span?style="font-family:Arial,?Helvetica,?sans-serif;">;</span>??
  • import?security.entity.SysUser;??
  • ??
  • public?class?SecurityUser?extends?SysUser?implements?UserDetails?{??
  • ????private?static?final?long?serialVersionUID?=?1L;??
  • ????public?SecurityUser(SysUser?suser)?{??
  • ????????if(suser?!=?null)??
  • ????????{??
  • ????????????this.setId(suser.getId());??
  • ????????????this.setName(suser.getName());??
  • ????????????this.setEmail(suser.getEmail());??
  • ????????????this.setPassword(suser.getPassword());??
  • ????????????this.setDob(suser.getDob());??
  • ????????????this.setSysRoles(suser.getSysRoles());??
  • ????????}?????????
  • ????}??
  • ??????
  • ????@Override??
  • ????public?Collection<??extends?GrantedAuthority>?getAuthorities()?{??
  • ??????????
  • ????????Collection<GrantedAuthority>?authorities?=?new?ArrayList<>();??
  • ????????Set<SysRole>?userRoles?=?this.getSysRoles();??
  • ??????????
  • ????????if(userRoles?!=?null)??
  • ????????{??
  • ????????????for?(SysRole?role?:?userRoles)?{??
  • ????????????????SimpleGrantedAuthority?authority?=?new?SimpleGrantedAuthority(role.getName());??
  • ????????????????authorities.add(authority);??
  • ????????????}??
  • ????????}??
  • ????????return?authorities;??
  • ????}??
  • ??
  • ????@Override??
  • ????public?String?getPassword()?{??
  • ????????return?super.getPassword();??
  • ????}??
  • ??
  • ????@Override??
  • ????public?String?getUsername()?{??
  • ????????return?super.getName();??
  • ????}??
  • ??
  • ????@Override??
  • ????public?boolean?isAccountNonExpired()?{??
  • ????????return?true;??
  • ????}??
  • ??
  • ????@Override??
  • ????public?boolean?isAccountNonLocked()?{??
  • ????????return?true;??
  • ????}??
  • ??
  • ????@Override??
  • ????public?boolean?isCredentialsNonExpired()?{??
  • ????????return?true;??
  • ????}??
  • ??
  • ????@Override??
  • ????public?boolean?isEnabled()?{??
  • ????????return?true;??
  • ????}??
  • }??
  • package security.support;import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails;import security.entity.SysRole; import security.entity.SysUser;public class SecurityUser extends SysUser implements UserDetails {private static final long serialVersionUID = 1L;public SecurityUser(SysUser suser) {if(suser != null){this.setId(suser.getId());this.setName(suser.getName());this.setEmail(suser.getEmail());this.setPassword(suser.getPassword());this.setDob(suser.getDob());this.setSysRoles(suser.getSysRoles());} }@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {Collection<GrantedAuthority> authorities = new ArrayList<>();Set<SysRole> userRoles = this.getSysRoles();if(userRoles != null){for (SysRole role : userRoles) {SimpleGrantedAuthority authority = new SimpleGrantedAuthority(role.getName());authorities.add(authority);}}return authorities;}@Overridepublic String getPassword() {return super.getPassword();}@Overridepublic String getUsername() {return super.getName();}@Overridepublic boolean isAccountNonExpired() {return true;}@Overridepublic boolean isAccountNonLocked() {return true;}@Overridepublic boolean isCredentialsNonExpired() {return true;}@Overridepublic boolean isEnabled() {return true;} }
    4、LoginSuccessHandler.java

    [java] view plaincopyprint?
  • package?security.support;??
  • ??
  • import?java.io.IOException;??
  • import?java.util.Set;??
  • ??
  • import?javax.servlet.ServletException;??
  • import?javax.servlet.http.HttpServletRequest;??
  • import?javax.servlet.http.HttpServletResponse;??
  • ??
  • import?org.springframework.security.core.Authentication;??
  • import?org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;??
  • ??
  • import?security.entity.SysRole;??
  • import?security.entity.SysUser;??
  • ??
  • public?class?LoginSuccessHandler?extends??
  • ????????SavedRequestAwareAuthenticationSuccessHandler?{??
  • ????@Override????
  • ????public?void?onAuthenticationSuccess(HttpServletRequest?request,????
  • ????????????HttpServletResponse?response,?Authentication?authentication)?throws?IOException,????
  • ????????????ServletException?{????
  • ????????//獲得授權(quán)后可得到用戶信息???可使用SUserService進(jìn)行數(shù)據(jù)庫操作??
  • ????????SysUser?userDetails?=?(SysUser)authentication.getPrincipal();????
  • ???????/*?Set<SysRole>?roles?=?userDetails.getSysRoles();*/??
  • ????????//輸出登錄提示信息????
  • ????????System.out.println("管理員?"?+?userDetails.getName()?+?"?登錄");????
  • ??????????
  • ????????System.out.println("IP?:"+getIpAddress(request));??
  • ????????????????
  • ????????super.onAuthenticationSuccess(request,?response,?authentication);????
  • ????}????
  • ??????
  • ????public?String?getIpAddress(HttpServletRequest?request){??????
  • ????????String?ip?=?request.getHeader("x-forwarded-for");??????
  • ????????if?(ip?==?null?||?ip.length()?==?0?||?"unknown".equalsIgnoreCase(ip))?{??????
  • ????????????ip?=?request.getHeader("Proxy-Client-IP");??????
  • ????????}??????
  • ????????if?(ip?==?null?||?ip.length()?==?0?||?"unknown".equalsIgnoreCase(ip))?{??????
  • ????????????ip?=?request.getHeader("WL-Proxy-Client-IP");??????
  • ????????}??????
  • ????????if?(ip?==?null?||?ip.length()?==?0?||?"unknown".equalsIgnoreCase(ip))?{??????
  • ????????????ip?=?request.getHeader("HTTP_CLIENT_IP");??????
  • ????????}??????
  • ????????if?(ip?==?null?||?ip.length()?==?0?||?"unknown".equalsIgnoreCase(ip))?{??????
  • ????????????ip?=?request.getHeader("HTTP_X_FORWARDED_FOR");??????
  • ????????}??????
  • ????????if?(ip?==?null?||?ip.length()?==?0?||?"unknown".equalsIgnoreCase(ip))?{??????
  • ????????????ip?=?request.getRemoteAddr();??????
  • ????????}??????
  • ????????return?ip;??????
  • ????}????
  • }??
  • package security.support;import java.io.IOException; import java.util.Set;import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;import security.entity.SysRole; import security.entity.SysUser;public class LoginSuccessHandler extendsSavedRequestAwareAuthenticationSuccessHandler {@Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { //獲得授權(quán)后可得到用戶信息 可使用SUserService進(jìn)行數(shù)據(jù)庫操作SysUser userDetails = (SysUser)authentication.getPrincipal(); /* Set<SysRole> roles = userDetails.getSysRoles();*///輸出登錄提示信息 System.out.println("管理員?" + userDetails.getName() + " 登錄"); System.out.println("IP :"+getIpAddress(request));super.onAuthenticationSuccess(request, response, authentication); } public String getIpAddress(HttpServletRequest request){ String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } } 5、MvcConfig.java

    [java] view plaincopyprint?
  • package?security;??
  • ??
  • import?org.springframework.context.annotation.Configuration;??
  • import?org.springframework.web.servlet.config.annotation.ViewControllerRegistry;??
  • import?org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;??
  • ??
  • @Configuration??
  • public?class?MvcConfig?extends?WebMvcConfigurerAdapter?{??
  • ??
  • ????@Override??
  • ????public?void?addViewControllers(ViewControllerRegistry?registry)?{??
  • ????????registry.addViewController("/home").setViewName("home");??
  • ????????registry.addViewController("/").setViewName("home");??
  • ????????registry.addViewController("/hello").setViewName("hello");??
  • ????????registry.addViewController("/login").setViewName("login");??
  • ????}??
  • ??
  • }??
  • package security;import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;@Configuration public class MvcConfig extends WebMvcConfigurerAdapter {@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/home").setViewName("home");registry.addViewController("/").setViewName("home");registry.addViewController("/hello").setViewName("hello");registry.addViewController("/login").setViewName("login");}}

    6、在resource下面創(chuàng)建templates目錄,然后放相關(guān)的html文件:

    home.html

    [html] view plaincopyprint?
  • <!DOCTYPE?html>??
  • <html?xmlns="http://www.w3.org/1999/xhtml"?xmlns:th="http://www.thymeleaf.org"?xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">??
  • ????<head>??
  • ????????<title>Spring?Security?Example</title>??
  • ????</head>??
  • ????<body>??
  • ????????<h1>Welcome!</h1>??
  • ??????????
  • ????????<p>Click?<a?th:href="@{/hello}">here</a>?to?see?a?greeting.</p>??
  • ????</body>??
  • </html>??
  • <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"><head><title>Spring Security Example</title></head><body><h1>Welcome!</h1><p>Click <a th:href="@{/hello}">here</a> to see a greeting.</p></body> </html>hello.html
    [html] view plaincopyprint?
  • <!DOCTYPE?html>??
  • <html?xmlns="http://www.w3.org/1999/xhtml"?xmlns:th="http://www.thymeleaf.org"??
  • ??????xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">??
  • ????<head>??
  • ????????<title>Hello?World!</title>??
  • ????</head>??
  • ????<body>??
  • ????????<h1?th:inline="text">Hello?[[${#httpServletRequest.remoteUser}]]!</h1>??
  • ????????<form?th:action="@{/logout}"?method="post">??
  • ????????????<input?type="submit"?value="Sign?Out"/>??
  • ????????</form>??
  • ????</body>??
  • </html>??
  • <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"><head><title>Hello World!</title></head><body><h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1><form th:action="@{/logout}" method="post"><input type="submit" value="Sign Out"/></form></body> </html>login.html
    [html] view plaincopyprint?
  • <!DOCTYPE?html>??
  • <html?xmlns="http://www.w3.org/1999/xhtml"?xmlns:th="http://www.thymeleaf.org"??
  • ??????xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">??
  • ????<head>??
  • ????????<title>Spring?Security?Example?</title>??
  • ????</head>??
  • ????<body>??
  • ????????<div?th:if="${param.error}">??
  • ????????????Invalid?username?and?password.??
  • ????????</div>??
  • ????????<div?th:if="${param.logout}">??
  • ????????????You?have?been?logged?out.??
  • ????????</div>??
  • ????????<form?th:action="@{/login}"?method="post">??
  • ????????????<div><label>?User?Name?:?<input?type="text"?name="username"/>?</label></div>??
  • ????????????<div><label>?Password:?<input?type="password"?name="password"/>?</label></div>??
  • ????????????<div><input?type="submit"?value="Sign?In"/></div>??
  • ????????????<input?type="checkbox"?name="remember-me"?value="true"?th:checked="checked"/><p>Remember?me</p>??
  • ????????</form>??
  • ????</body>??
  • </html>??
  • <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"><head><title>Spring Security Example </title></head><body><div th:if="${param.error}">Invalid username and password.</div><div th:if="${param.logout}">You have been logged out.</div><form th:action="@{/login}" method="post"><div><label> User Name : <input type="text" name="username"/> </label></div><div><label> Password: <input type="password" name="password"/> </label></div><div><input type="submit" value="Sign In"/></div><input type="checkbox" name="remember-me" value="true" th:checked="checked"/><p>Remember?me</p></form></body> </html>接下來是主類:MainApplication.java

    [java] view plaincopyprint?
  • package?security;??
  • ??
  • import?org.springframework.boot.SpringApplication;??
  • import?org.springframework.boot.autoconfigure.SpringBootApplication;??
  • import?org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;??
  • import?org.springframework.web.servlet.config.annotation.ViewControllerRegistry;??
  • import?org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;??
  • ??
  • import?security.entity.SysUser;??
  • import?security.entity.User;??
  • import?security.service.UserService;??
  • import?security.Appctx;??
  • ??
  • @SpringBootApplication??
  • public?class?MainApplication{??
  • ????public?static?void?main(String[]?args)?{??
  • ????????//SpringApplication.run(MainApplication.class,?args);??
  • ????????SpringApplication?app=new?SpringApplication(MainApplication.class);???????
  • ??????????
  • ????????Appctx.ctx=app.run(args);??
  • ????????/*UserService?suserService?=?(UserService)?Appctx.ctx.getBean("suserService");?
  • ????????SysUser?su=?suserService.findByName("TEST");?
  • ????????BCryptPasswordEncoder?bc=new?BCryptPasswordEncoder(4);//將密碼加密?可以先設(shè)置初始密碼:000000??
  • ????????su.setPassword(bc.encode(su.getPassword()));//然后使用密碼為key值進(jìn)行加密,運(yùn)行主類后,會自動加密密碼,可連接數(shù)據(jù)庫查看。?
  • ????????System.out.println("密碼"+su.getPassword());?
  • ????????suserService.update(su);//運(yùn)行一次后記得注釋這段重復(fù)加密會無法匹配*/??
  • ????}??
  • }??
  • package security;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import security.entity.SysUser; import security.entity.User; import security.service.UserService; import security.Appctx;@SpringBootApplication public class MainApplication{public static void main(String[] args) {//SpringApplication.run(MainApplication.class, args);SpringApplication app=new SpringApplication(MainApplication.class); Appctx.ctx=app.run(args);/*UserService suserService = (UserService) Appctx.ctx.getBean("suserService");SysUser su= suserService.findByName("TEST");BCryptPasswordEncoder bc=new BCryptPasswordEncoder(4);//將密碼加密 可以先設(shè)置初始密碼:000000 su.setPassword(bc.encode(su.getPassword()));//然后使用密碼為key值進(jìn)行加密,運(yùn)行主類后,會自動加密密碼,可連接數(shù)據(jù)庫查看。System.out.println("密碼"+su.getPassword());suserService.update(su);//運(yùn)行一次后記得注釋這段重復(fù)加密會無法匹配*/} }
    Appctx.java

    [java] view plaincopyprint?
  • package?security.support;??
  • ??
  • import?org.springframework.context.ApplicationContext;??
  • ??
  • public?class?Appctx?{??
  • ????public?static?ApplicationContext?ctx=null;???
  • ????public?static?Object?getObject(String?string){??
  • ????????return?ctx.getBean(string);??
  • ????}??
  • }??
  • package security.support;import org.springframework.context.ApplicationContext;public class Appctx {public static ApplicationContext ctx=null; public static Object getObject(String string){return ctx.getBean(string);} }

    1.?運(yùn)行,訪問http://localhost:8080/hello,系統(tǒng)出現(xiàn)如下界面:


    登陸成功后:

    登陸擁有ADMIN權(quán)限的用戶,可以進(jìn)入/home

    如果用戶不具有權(quán)限,會出現(xiàn)以下:

    好了,根據(jù)配置:.antMatchers("/hello").hasAuthority("ADMIN")。來進(jìn)行權(quán)限控制,就到這里,下面,我們來根據(jù)數(shù)據(jù)庫中的資源和權(quán)限的關(guān)系,進(jìn)行授權(quán)和認(rèn)證


    1、CustomInvocationSecurityMetadataSourceService.java 參照流程圖

    [java] view plaincopyprint?
  • /*?
  • ?*?@(#)?MyInvocationSecurityMetadataSourceService.java??2011-3-23?下午02:58:29?
  • ?*?
  • ?*?Copyright?2011?by?Sparta??
  • ?*/??
  • ??
  • package?security.support;??
  • ??
  • import?java.util.ArrayList;??
  • import?java.util.Collection;??
  • import?java.util.HashMap;??
  • import?java.util.Iterator;??
  • import?java.util.List;??
  • import?java.util.Map;??
  • import?java.util.Map.Entry;??
  • import?java.util.Set;??
  • ??
  • import?javax.annotation.PostConstruct;??
  • ??
  • import?org.hibernate.Session;??
  • import?org.hibernate.SessionFactory;??
  • import?org.springframework.beans.factory.annotation.Autowired;??
  • import?org.springframework.context.ApplicationContext;??
  • import?org.springframework.context.support.ClassPathXmlApplicationContext;??
  • import?org.springframework.security.access.ConfigAttribute;??
  • import?org.springframework.security.access.SecurityConfig;??
  • import?org.springframework.security.core.GrantedAuthority;??
  • import?org.springframework.security.core.context.SecurityContextHolder;??
  • import?org.springframework.security.core.userdetails.UserDetails;??
  • import?org.springframework.security.web.FilterInvocation;??
  • import?org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;??
  • import?org.springframework.security.web.util.matcher.AntPathRequestMatcher;??
  • import?org.springframework.security.web.util.matcher.RequestMatcher;??
  • import?org.springframework.stereotype.Component;??
  • import?org.springframework.stereotype.Service;??
  • ??
  • import?security.dao.SResourceVODao;??
  • import?security.dao.SRoleDao;??
  • import?security.dao.SRoleVODao;??
  • import?security.entity.SRole;??
  • import?security.service.SResourceService;??
  • import?security.service.SRoleService;??
  • ??
  • /**?
  • ?*?最核心的地方,就是提供某個資源對應(yīng)的權(quán)限定義,即getAttributes方法返回的結(jié)果。?此類在初始化時,應(yīng)該取到所有資源及其對應(yīng)角色的定義。?
  • ?*??
  • ?*/??
  • @Service??
  • public?class?CustomInvocationSecurityMetadataSourceService?implements??
  • ????????FilterInvocationSecurityMetadataSource?{??
  • ??????
  • ????@Autowired??
  • ????private?SResourceVODao?sResourceVODao;??
  • ??????
  • ????@Autowired??
  • ????private?SRoleVODao?sRoleVODao;??
  • ??????
  • ????private?static?Map<String,?Collection<ConfigAttribute>>?resourceMap?=?null;??
  • ??
  • ????/*public?CustomInvocationSecurityMetadataSourceService(SResourceService?sres,SRoleService?sR)?{?
  • ????????this.sResourceService?=?sres;?
  • ????????this.sRoleService?=?sR;?
  • ????????loadResourceDefine();?
  • ????}*/??
  • ????@PostConstruct<span?style="color:#33cc00;">//<span?style="font-family:Helvetica,?Tahoma,?Arial,?sans-serif;font-size:14px;line-height:25.1875px;">??</span><span?style="font-family:Helvetica,?Tahoma,?Arial,?sans-serif;line-height:25.1875px;"><span?style="font-size:10px;">被@PostConstruct修飾的方法會在服務(wù)器加載Servle的時候運(yùn)行,并且只會被服務(wù)器執(zhí)行一次。PostConstruct在構(gòu)造函數(shù)之后執(zhí)行,init()方法之前執(zhí)行。</span></span></span>??
  • ????private?void?loadResourceDefine()?{??<span?style="color:#33cc00;">?//一定要加上<span?style="font-family:Arial,?Helvetica,?sans-serif;">@PostConstruct注解</span></span>??
  • ????<span?style="color:#33cc00;">//?在Web服務(wù)器啟動時,提取系統(tǒng)中的所有權(quán)限。</span>??
  • ????????List<Map<String,Object>>?list?=sRoleVODao.findAll();??
  • ????????List<String>?query?=?new?ArrayList<String>();??
  • ????????if(list!=null?&&?list.size()>0)?{??
  • ????????????for(Map<String,Object>?sr?:list){??
  • ????????????????//String?name?=?sr.get("name")????
  • ????????????????Object?value?=?sr.get("name");??
  • ????????????????String?name?=?String.valueOf(value);??
  • ????????????????query.add(name);??
  • ????????????}??
  • ????????}??
  • ????????<span?style="color:#33cc00;">/*?
  • ?????????*?應(yīng)當(dāng)是資源為key,?權(quán)限為value。?資源通常為url,?權(quán)限就是那些以ROLE_為前綴的角色。?一個資源可以由多個權(quán)限來訪問。?
  • ?????????*?sparta?
  • ?????????*/</span>??
  • ????????resourceMap?=?new?HashMap<String,?Collection<ConfigAttribute>>();??
  • ??
  • ????????for?(String?auth?:?query)?{??
  • ????????????ConfigAttribute?ca?=?new?SecurityConfig(auth);??
  • ????????????//List<Map<String,Object>>?query1?=?sResourceVODao.findByRoleName(auth);??
  • ????????????List<String>?query1?=?new?ArrayList<String>();??
  • ????????????List<Map<String,?Object>>??list1?=?sResourceVODao.findByRoleName(auth);??
  • ????????????if(list1!=null?&&?list1.size()>0)?{??
  • ????????????????for(Map<String,?Object>?map?:list1){??
  • ????????????????????Object?value?=?map.get("resource_string");??
  • ????????????????????String?url?=?String.valueOf(value);??
  • ????????????????????query1.add(url);??
  • ????????????????}??
  • ????????????}??
  • ????????????for?(String?res?:?query1)?{??
  • ????????????????String?url?=?res;??
  • ??????????????????
  • ????????????????<span?style="color:#33cc00;">/*?
  • ?????????????????*?判斷資源文件和權(quán)限的對應(yīng)關(guān)系,如果已經(jīng)存在相關(guān)的資源url,則要通過該url為key提取出權(quán)限集合,將權(quán)限增加到權(quán)限集合中。?
  • ?????????????????*?sparta?
  • ?????????????????*/</span>??
  • ????????????????if?(resourceMap.containsKey(url))?{??
  • ??
  • ????????????????????Collection<ConfigAttribute>?value?=?resourceMap.get(url);??
  • ????????????????????value.add(ca);??
  • ????????????????????resourceMap.put(url,?value);??
  • ????????????????}?else?{??
  • ????????????????????Collection<ConfigAttribute>?atts?=?new?ArrayList<ConfigAttribute>();??
  • ????????????????????atts.add(ca);??
  • ????????????????????resourceMap.put(url,?atts);??
  • ????????????????}??
  • ??
  • ????????????}??
  • ????????}??
  • ??
  • ????}??
  • ??
  • ????@Override??
  • ????public?Collection<ConfigAttribute>?getAllConfigAttributes()?{??
  • ?????????return?new?ArrayList<ConfigAttribute>();??
  • ????}??
  • <span?style="color:#33cc00;">??
  • ????//?根據(jù)URL,找到相關(guān)的權(quán)限配置。</span>??
  • ????@Override??
  • ????public?Collection<ConfigAttribute>?getAttributes(Object?object)??
  • ????????????throws?IllegalArgumentException?{??
  • ????????System.out.println("nwuidhwuiehdfu");??
  • ????????<span?style="color:#33cc00;">//?object?是一個URL,被用戶請求的url。</span>??
  • ????????FilterInvocation?filterInvocation?=?(FilterInvocation)?object;??
  • ????????if?(resourceMap?==?null)?{??
  • ????????????loadResourceDefine();??
  • ????????}??
  • ????????Iterator<String>?ite?=?resourceMap.keySet().iterator();??
  • ????????while?(ite.hasNext())?{??
  • ????????????String?resURL?=?ite.next();??
  • ?????????????RequestMatcher?requestMatcher?=?new?AntPathRequestMatcher(resURL);??
  • ????????????????if(requestMatcher.matches(filterInvocation.getHttpRequest()))?{??
  • ????????????????return?resourceMap.get(resURL);??
  • ????????????}??
  • ????????}??
  • ??
  • ????????return?null;??
  • ????}??
  • ????@Override??
  • ????public?boolean?supports(Class<?>?arg0)?{??
  • ??
  • ????????return?true;??
  • ????}??
  • ??
  • }??
  • /** @(#) MyInvocationSecurityMetadataSourceService.java 2011-3-23 下午02:58:29** Copyright 2011 by Sparta */package security.support;import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set;import javax.annotation.PostConstruct;import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service;import security.dao.SResourceVODao; import security.dao.SRoleDao; import security.dao.SRoleVODao; import security.entity.SRole; import security.service.SResourceService; import security.service.SRoleService;/*** 最核心的地方,就是提供某個資源對應(yīng)的權(quán)限定義,即getAttributes方法返回的結(jié)果。 此類在初始化時,應(yīng)該取到所有資源及其對應(yīng)角色的定義。* */ @Service public class CustomInvocationSecurityMetadataSourceService implementsFilterInvocationSecurityMetadataSource {@Autowiredprivate SResourceVODao sResourceVODao;@Autowiredprivate SRoleVODao sRoleVODao;private static Map<String, Collection<ConfigAttribute>> resourceMap = null;/*public CustomInvocationSecurityMetadataSourceService(SResourceService sres,SRoleService sR) {this.sResourceService = sres;this.sRoleService = sR;loadResourceDefine();}*/@PostConstruct//? 被@PostConstruct修飾的方法會在服務(wù)器加載Servle的時候運(yùn)行,并且只會被服務(wù)器執(zhí)行一次。PostConstruct在構(gòu)造函數(shù)之后執(zhí)行,init()方法之前執(zhí)行。private void loadResourceDefine() { //一定要加上@PostConstruct注解// 在Web服務(wù)器啟動時,提取系統(tǒng)中的所有權(quán)限。List<Map<String,Object>> list =sRoleVODao.findAll();List<String> query = new ArrayList<String>();if(list!=null && list.size()>0) {for(Map<String,Object> sr :list){//String name = sr.get("name") Object value = sr.get("name");String name = String.valueOf(value);query.add(name);}}/** 應(yīng)當(dāng)是資源為key, 權(quán)限為value。 資源通常為url, 權(quán)限就是那些以ROLE_為前綴的角色。 一個資源可以由多個權(quán)限來訪問。* sparta*/resourceMap = new HashMap<String, Collection<ConfigAttribute>>();for (String auth : query) {ConfigAttribute ca = new SecurityConfig(auth);//List<Map<String,Object>> query1 = sResourceVODao.findByRoleName(auth);List<String> query1 = new ArrayList<String>();List<Map<String, Object>> list1 = sResourceVODao.findByRoleName(auth);if(list1!=null && list1.size()>0) {for(Map<String, Object> map :list1){Object value = map.get("resource_string");String url = String.valueOf(value);query1.add(url);}}for (String res : query1) {String url = res;/** 判斷資源文件和權(quán)限的對應(yīng)關(guān)系,如果已經(jīng)存在相關(guān)的資源url,則要通過該url為key提取出權(quán)限集合,將權(quán)限增加到權(quán)限集合中。* sparta*/if (resourceMap.containsKey(url)) {Collection<ConfigAttribute> value = resourceMap.get(url);value.add(ca);resourceMap.put(url, value);} else {Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();atts.add(ca);resourceMap.put(url, atts);}}}}@Overridepublic Collection<ConfigAttribute> getAllConfigAttributes() {return new ArrayList<ConfigAttribute>();} // 根據(jù)URL,找到相關(guān)的權(quán)限配置。@Overridepublic Collection<ConfigAttribute> getAttributes(Object object)throws IllegalArgumentException {System.out.println("nwuidhwuiehdfu");// object 是一個URL,被用戶請求的url。FilterInvocation filterInvocation = (FilterInvocation) object;if (resourceMap == null) {loadResourceDefine();}Iterator<String> ite = resourceMap.keySet().iterator();while (ite.hasNext()) {String resURL = ite.next();RequestMatcher requestMatcher = new AntPathRequestMatcher(resURL);if(requestMatcher.matches(filterInvocation.getHttpRequest())) {return resourceMap.get(resURL);}}return null;}@Overridepublic boolean supports(Class<?> arg0) {return true;}} 2、CustomAccessDecisionManager.java

    [html] view plaincopyprint?
  • /*??
  • ?*?@(#)?MyAccessDecisionManager.java??2011-3-23?下午04:41:12??
  • ?*??
  • ?*?Copyright?2011?by?Sparta???
  • ?*/??
  • ??
  • package?security.support;??
  • ??
  • import?java.util.Collection;??
  • import?java.util.Iterator;??
  • ??
  • import?org.springframework.security.access.AccessDecisionManager;??
  • import?org.springframework.security.access.AccessDeniedException;??
  • import?org.springframework.security.access.ConfigAttribute;??
  • import?org.springframework.security.access.SecurityConfig;??
  • import?org.springframework.security.authentication.InsufficientAuthenticationException;??
  • import?org.springframework.security.core.Authentication;??
  • import?org.springframework.security.core.GrantedAuthority;??
  • import?org.springframework.stereotype.Component;??
  • import?org.springframework.stereotype.Service;??
  • ??
  • <span?style="color:#33cc00;">/**??
  • ?*AccessdecisionManager在Spring?security中是很重要的。??
  • ?*??
  • ?*在驗證部分簡略提過了,所有的Authentication實現(xiàn)需要保存在一個GrantedAuthority對象數(shù)組中。???
  • ?*這就是賦予給主體的權(quán)限。?GrantedAuthority對象通過AuthenticationManager??
  • ?*保存到?Authentication對象里,然后從AccessDecisionManager讀出來,進(jìn)行授權(quán)判斷。???
  • ?*??
  • ?*Spring?Security提供了一些攔截器,來控制對安全對象的訪問權(quán)限,例如方法調(diào)用或web請求。???
  • ?*一個是否允許執(zhí)行調(diào)用的預(yù)調(diào)用決定,是由AccessDecisionManager實現(xiàn)的。???
  • ?*這個?AccessDecisionManager?被AbstractSecurityInterceptor調(diào)用,??
  • ?*它用來作最終訪問控制的決定。?這個AccessDecisionManager接口包含三個方法:???
  • ?*??
  • ?void?decide(Authentication?authentication,?Object?secureObject,??
  • ????List<ConfigAttributeDefinition>?config)?throws?AccessDeniedException;??
  • ?boolean?supports(ConfigAttribute?attribute);??
  • ?boolean?supports(Class?clazz);??
  • ???
  • ??從第一個方法可以看出來,AccessDecisionManager使用方法參數(shù)傳遞所有信息,這好像在認(rèn)證評估時進(jìn)行決定。???
  • ??特別是,在真實的安全方法期望調(diào)用的時候,傳遞安全Object啟用那些參數(shù)。???
  • ??比如,讓我們假設(shè)安全對象是一個MethodInvocation。???
  • ??很容易為任何Customer參數(shù)查詢MethodInvocation,??
  • ??然后在AccessDecisionManager里實現(xiàn)一些有序的安全邏輯,來確認(rèn)主體是否允許在那個客戶上操作。???
  • ??如果訪問被拒絕,實現(xiàn)將拋出一個AccessDeniedException異常。??
  • ??
  • ??這個?supports(ConfigAttribute)?方法在啟動的時候被??
  • ??AbstractSecurityInterceptor調(diào)用,來決定AccessDecisionManager??
  • ??是否可以執(zhí)行傳遞ConfigAttribute。???
  • ??supports(Class)方法被安全攔截器實現(xiàn)調(diào)用,??
  • ??包含安全攔截器將顯示的AccessDecisionManager支持安全對象的類型。??
  • ?*/</span>??
  • @Service??
  • public?class?CustomAccessDecisionManager?implements?AccessDecisionManager?{??
  • ??????
  • ????public?void?decide(?Authentication?authentication,?Object?object,???
  • ????????????Collection<ConfigAttribute>?configAttributes)???
  • ????????throws?AccessDeniedException,?InsufficientAuthenticationException{??
  • ????????if(?configAttributes?==?null?)?{??
  • ????????????return?;??
  • ????????}??
  • ??????????
  • ????????Iterator<ConfigAttribute>?ite?=?configAttributes.iterator();??
  • ??????????
  • ????????while(?ite.hasNext()){??
  • ????????????ConfigAttribute?ca?=?ite.next();??
  • ????????????String?needRole?=?((SecurityConfig)ca).getAttribute();??
  • ??????????????
  • ????????<span?style="color:#33cc00;">???//ga?為用戶所被賦予的權(quán)限。?needRole?為訪問相應(yīng)的資源應(yīng)該具有的權(quán)限。</span>??
  • ????????????for(?GrantedAuthority?ga:?authentication.getAuthorities()){??
  • ??????????????????
  • ????????????????if(needRole.trim().equals(ga.getAuthority().trim())){??
  • ??
  • ????????????????????return;??
  • ????????????????}??
  • ??????????????????
  • ????????????}??
  • ??????????????
  • ????????}??
  • ??????????
  • ????????throw?new?AccessDeniedException("權(quán)限不足");??
  • ??????????
  • ????}??
  • ??????
  • ????public?boolean?supports(?ConfigAttribute?attribute?){??
  • ????????<span?style="color:#ff0000;">return?true;</span><span?style="color:#33cc00;">//都要設(shè)為true</span>??
  • ??
  • ????}??
  • ??????
  • ????public?boolean?supports(Class<?>?clazz){??
  • ????????<span?style="color:#ff0000;">return?true;</span><span?style="color:rgb(51,204,0);font-family:Arial,?Helvetica,?sans-serif;">//都要設(shè)為true</span>??
  • ????}??
  • ??????
  • ??
  • }??
  • /** @(#) MyAccessDecisionManager.java 2011-3-23 下午04:41:12** Copyright 2011 by Sparta */package security.support;import java.util.Collection; import java.util.Iterator;import org.springframework.security.access.AccessDecisionManager; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service;/***AccessdecisionManager在Spring security中是很重要的。**在驗證部分簡略提過了,所有的Authentication實現(xiàn)需要保存在一個GrantedAuthority對象數(shù)組中。 *這就是賦予給主體的權(quán)限。 GrantedAuthority對象通過AuthenticationManager*保存到 Authentication對象里,然后從AccessDecisionManager讀出來,進(jìn)行授權(quán)判斷。 **Spring Security提供了一些攔截器,來控制對安全對象的訪問權(quán)限,例如方法調(diào)用或web請求。 *一個是否允許執(zhí)行調(diào)用的預(yù)調(diào)用決定,是由AccessDecisionManager實現(xiàn)的。 *這個 AccessDecisionManager 被AbstractSecurityInterceptor調(diào)用,*它用來作最終訪問控制的決定。 這個AccessDecisionManager接口包含三個方法: *void decide(Authentication authentication, Object secureObject,List<ConfigAttributeDefinition> config) throws AccessDeniedException;boolean supports(ConfigAttribute attribute);boolean supports(Class clazz);從第一個方法可以看出來,AccessDecisionManager使用方法參數(shù)傳遞所有信息,這好像在認(rèn)證評估時進(jìn)行決定。 特別是,在真實的安全方法期望調(diào)用的時候,傳遞安全Object啟用那些參數(shù)。 比如,讓我們假設(shè)安全對象是一個MethodInvocation。 很容易為任何Customer參數(shù)查詢MethodInvocation,然后在AccessDecisionManager里實現(xiàn)一些有序的安全邏輯,來確認(rèn)主體是否允許在那個客戶上操作。 如果訪問被拒絕,實現(xiàn)將拋出一個AccessDeniedException異常。這個 supports(ConfigAttribute) 方法在啟動的時候被AbstractSecurityInterceptor調(diào)用,來決定AccessDecisionManager是否可以執(zhí)行傳遞ConfigAttribute。 supports(Class)方法被安全攔截器實現(xiàn)調(diào)用,包含安全攔截器將顯示的AccessDecisionManager支持安全對象的類型。*/ @Service public class CustomAccessDecisionManager implements AccessDecisionManager {public void decide( Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException{if( configAttributes == null ) {return ;}Iterator<ConfigAttribute> ite = configAttributes.iterator();while( ite.hasNext()){ConfigAttribute ca = ite.next();String needRole = ((SecurityConfig)ca).getAttribute(); //ga 為用戶所被賦予的權(quán)限。 needRole 為訪問相應(yīng)的資源應(yīng)該具有的權(quán)限。for( GrantedAuthority ga: authentication.getAuthorities()){if(needRole.trim().equals(ga.getAuthority().trim())){return;}}}throw new AccessDeniedException("權(quán)限不足");}public boolean supports( ConfigAttribute attribute ){return true;//都要設(shè)為true}public boolean supports(Class<?> clazz){return true;//都要設(shè)為true}}

    3、?MyFilterSecurityInterceptor.java

    [java] view plaincopyprint?
  • /*?
  • ?*?@(#)?MyFilterSecurityInterceptor.java??2011-3-23?上午07:53:03?
  • ?*?
  • ?*?Copyright?2011?by?Sparta??
  • ?*/??
  • ??
  • package?security.support;??
  • ??
  • import?java.io.IOException;??
  • import?java.util.Collection;??
  • import?java.util.Map;??
  • ??
  • import?javax.annotation.PostConstruct;??
  • import?javax.servlet.Filter;??
  • import?javax.servlet.FilterChain;??
  • import?javax.servlet.FilterConfig;??
  • import?javax.servlet.ServletException;??
  • import?javax.servlet.ServletRequest;??
  • import?javax.servlet.ServletResponse;??
  • ??
  • import?org.springframework.beans.factory.annotation.Autowired;??
  • import?org.springframework.security.access.ConfigAttribute;??
  • import?org.springframework.security.access.SecurityMetadataSource;??
  • import?org.springframework.security.access.intercept.AbstractSecurityInterceptor;??
  • import?org.springframework.security.access.intercept.InterceptorStatusToken;??
  • import?org.springframework.security.authentication.AuthenticationManager;??
  • import?org.springframework.security.web.FilterInvocation;??
  • import?org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;??
  • import?security.service.SResourceService;??
  • ??
  • /**?
  • ?*?該過濾器的主要作用就是通過spring著名的IoC生成securityMetadataSource。?
  • ?*?securityMetadataSource相當(dāng)于本包中自定義的MyInvocationSecurityMetadataSourceService。?
  • ?*?該MyInvocationSecurityMetadataSourceService的作用提從數(shù)據(jù)庫提取權(quán)限和資源,裝配到HashMap中,?
  • ?*?供Spring?Security使用,用于權(quán)限校驗。?
  • ?*?@author?sparta?11/3/29?
  • ?*?
  • ?*/??
  • @Component??
  • public?class?MySecurityFilter???
  • ????extends?AbstractSecurityInterceptor??
  • ????implements?Filter{??
  • ????@Autowired??
  • ????private?CustomInvocationSecurityMetadataSourceService??mySecurityMetadataSource;??
  • ??????
  • ????@Autowired??
  • ????private?CustomAccessDecisionManager?myAccessDecisionManager;??
  • ??????
  • ????@Autowired??
  • ????private?AuthenticationManager?authenticationManager;??
  • ??????
  • ??????
  • ????@PostConstruct??
  • ????public?void?init(){??
  • ????????super.setAuthenticationManager(authenticationManager);??
  • ????????super.setAccessDecisionManager(myAccessDecisionManager);??
  • ????}??
  • ??????
  • ????public?void?doFilter(?ServletRequest?request,?ServletResponse?response,?FilterChain?chain)??
  • ????throws?IOException,?ServletException{??
  • ????????FilterInvocation?fi?=?new?FilterInvocation(?request,?response,?chain?);??
  • ????????invoke(fi);??
  • ??????????
  • ????}??
  • ??
  • ??????
  • ????public?Class<??extends?Object>?getSecureObjectClass(){??
  • ????????return?FilterInvocation.class;??
  • ????}??
  • ??
  • ??????
  • ????public?void?invoke(?FilterInvocation?fi?)?throws?IOException,?ServletException{??
  • ????????System.out.println("filter..........................");??
  • ????????InterceptorStatusToken??token?=?super.beforeInvocation(fi);??
  • ????????try{??
  • ????????????fi.getChain().doFilter(fi.getRequest(),?fi.getResponse());??
  • ????????}finally{??
  • ????????????super.afterInvocation(token,?null);??
  • ????????}??
  • ??????????
  • ????}??
  • ??????????
  • ??????
  • ????@Override??
  • ????public?SecurityMetadataSource?obtainSecurityMetadataSource(){??
  • ????????System.out.println("filtergergetghrthetyetyetyetyj");??
  • ????????return?this.mySecurityMetadataSource;??
  • ????}??
  • ??????
  • ????public?void?destroy(){??
  • ????????System.out.println("filter===========================end");??
  • ????}??
  • ????public?void?init(?FilterConfig?filterconfig?)?throws?ServletException{??
  • ????????System.out.println("filter===========================");??
  • ????}??
  • }??
  • /** @(#) MyFilterSecurityInterceptor.java 2011-3-23 上午07:53:03** Copyright 2011 by Sparta */package security.support;import java.io.IOException; import java.util.Collection; import java.util.Map;import javax.annotation.PostConstruct; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityMetadataSource; import org.springframework.security.access.intercept.AbstractSecurityInterceptor; import org.springframework.security.access.intercept.InterceptorStatusToken; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import security.service.SResourceService;/*** 該過濾器的主要作用就是通過spring著名的IoC生成securityMetadataSource。* securityMetadataSource相當(dāng)于本包中自定義的MyInvocationSecurityMetadataSourceService。* 該MyInvocationSecurityMetadataSourceService的作用提從數(shù)據(jù)庫提取權(quán)限和資源,裝配到HashMap中,* 供Spring Security使用,用于權(quán)限校驗。* @author sparta 11/3/29**/ @Component public class MySecurityFilter extends AbstractSecurityInterceptorimplements Filter{@Autowiredprivate CustomInvocationSecurityMetadataSourceService mySecurityMetadataSource;@Autowiredprivate CustomAccessDecisionManager myAccessDecisionManager;@Autowiredprivate AuthenticationManager authenticationManager;@PostConstructpublic void init(){super.setAuthenticationManager(authenticationManager);super.setAccessDecisionManager(myAccessDecisionManager);}public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException{FilterInvocation fi = new FilterInvocation( request, response, chain );invoke(fi);}public Class<? extends Object> getSecureObjectClass(){return FilterInvocation.class;}public void invoke( FilterInvocation fi ) throws IOException, ServletException{System.out.println("filter..........................");InterceptorStatusToken token = super.beforeInvocation(fi);try{fi.getChain().doFilter(fi.getRequest(), fi.getResponse());}finally{super.afterInvocation(token, null);}}@Overridepublic SecurityMetadataSource obtainSecurityMetadataSource(){System.out.println("filtergergetghrthetyetyetyetyj");return this.mySecurityMetadataSource;}public void destroy(){System.out.println("filter===========================end");}public void init( FilterConfig filterconfig ) throws ServletException{System.out.println("filter===========================");} }
    接下來修改一個類的 大家注意:
    WebSecurityConfig.java

    [java] view plaincopyprint?
  • package?security;??
  • ??
  • import?org.springframework.beans.factory.annotation.Autowired;??
  • import?org.springframework.boot.autoconfigure.security.SecurityProperties;??
  • import?org.springframework.boot.web.servlet.FilterRegistrationBean;??
  • import?org.springframework.context.annotation.Bean;??
  • import?org.springframework.context.annotation.Configuration;??
  • import?org.springframework.core.annotation.Order;??
  • import?org.springframework.security.authentication.AuthenticationManager;??
  • import?org.springframework.security.authentication.AuthenticationProvider;??
  • 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.builders.WebSecurity;??
  • import?org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;??
  • import?org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;??
  • import?org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;??
  • import?org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;??
  • import?org.springframework.security.web.access.intercept.FilterSecurityInterceptor;??
  • ??
  • import?security.support.CustomUserDetailsService;??
  • import?security.support.LoginSuccessHandler;??
  • import?security.support.MySecurityFilter;??
  • @Configuration??
  • @EnableWebSecurity??
  • public?class?WebSecurityConfig?extends?WebSecurityConfigurerAdapter?{??
  • ??????
  • ????@Autowired??
  • ????private?MyFilterSecurityInterceptor?mySecurityFilter;??
  • ??????
  • ????@Autowired??
  • ????private?CustomUserDetailsService?customUserDetailsService;??
  • ??????
  • ????@Override??
  • ????public?AuthenticationManager?authenticationManagerBean()?throws?Exception?{??
  • ???????
  • ????return?super.authenticationManagerBean();??
  • ???????
  • ????}??
  • ????//http://localhost:8080/login?輸入正確的用戶名密碼?并且選中remember-me?則登陸成功,轉(zhuǎn)到?index頁面???
  • ????//再次訪問index頁面無需登錄直接訪問??
  • ????//訪問http://localhost:8080/home?不攔截,直接訪問,??
  • ????//訪問http://localhost:8080/hello?需要登錄驗證后,且具備?“ADMIN”權(quán)限hasAuthority("ADMIN")才可以訪問??
  • ????@Override??
  • ????protected?void?configure(HttpSecurity?http)?throws?Exception?{??
  • ????????http??
  • ????????.addFilterBefore(mySecurityFilter,?FilterSecurityInterceptor.class)//在正確的位置添加我們自定義的過濾器??
  • ????????.authorizeRequests()??
  • ????????.antMatchers("/home").permitAll()??
  • ????????.anyRequest().authenticated()??
  • ????????//.antMatchers("/hello").hasAuthority("ADMIN")??
  • ????????.and()??
  • ????????.formLogin()??
  • ????????.loginPage("/login")??????
  • ????????.permitAll()??
  • ????????.successHandler(loginSuccessHandler())//code3??
  • ????????.and()??
  • ????????.logout()??
  • ????????.logoutSuccessUrl("/home")??
  • ????????.permitAll()??
  • ????????.invalidateHttpSession(true)??
  • ????????.and()??
  • ????????.rememberMe()??
  • ????????.tokenValiditySeconds(1209600);??
  • ????}??
  • ????@Override??
  • ????????public?void?configure(WebSecurity?web)?throws?Exception?{??
  • ????????????super.configure(web);??
  • ????}??
  • ????@Autowired??
  • ????public?void?configureGlobal(AuthenticationManagerBuilder?auth)?throws?Exception?{?????
  • //指定密碼加密所使用的加密器為passwordEncoder()??
  • //需要將密碼加密后寫入數(shù)據(jù)庫???
  • ????auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());??
  • //不刪除憑據(jù),以便記住用戶??
  • ????????auth.eraseCredentials(false);?????????
  • ????}??
  • ??????
  • ????//?Code5----------------------------------------------??
  • ????@Bean??
  • ????public?BCryptPasswordEncoder?passwordEncoder()?{??
  • ????????return?new?BCryptPasswordEncoder(4);??
  • ????}??
  • ??
  • ????//?Code3----------------------------------------------??
  • ????@Bean??
  • ????public?LoginSuccessHandler?loginSuccessHandler(){??
  • ????????return?new?LoginSuccessHandler();??
  • ????}??
  • }??
  • package security;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationProvider; 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.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;import security.support.CustomUserDetailsService; import security.support.LoginSuccessHandler; import security.support.MySecurityFilter; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate MyFilterSecurityInterceptor mySecurityFilter;@Autowiredprivate CustomUserDetailsService customUserDetailsService;@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}//http://localhost:8080/login 輸入正確的用戶名密碼 并且選中remember-me 則登陸成功,轉(zhuǎn)到 index頁面 //再次訪問index頁面無需登錄直接訪問//訪問http://localhost:8080/home 不攔截,直接訪問,//訪問http://localhost:8080/hello 需要登錄驗證后,且具備 “ADMIN”權(quán)限hasAuthority("ADMIN")才可以訪問@Overrideprotected void configure(HttpSecurity http) throws Exception {http.addFilterBefore(mySecurityFilter, FilterSecurityInterceptor.class)//在正確的位置添加我們自定義的過濾器.authorizeRequests().antMatchers("/home").permitAll().anyRequest().authenticated()//.antMatchers("/hello").hasAuthority("ADMIN").and().formLogin().loginPage("/login") .permitAll().successHandler(loginSuccessHandler())//code3.and().logout().logoutSuccessUrl("/home").permitAll().invalidateHttpSession(true).and().rememberMe().tokenValiditySeconds(1209600);}@Overridepublic void configure(WebSecurity web) throws Exception {super.configure(web);}@Autowiredpublic void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { //指定密碼加密所使用的加密器為passwordEncoder() //需要將密碼加密后寫入數(shù)據(jù)庫 auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder()); //不刪除憑據(jù),以便記住用戶auth.eraseCredentials(false); }// Code5----------------------------------------------@Beanpublic BCryptPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder(4);}// Code3----------------------------------------------@Beanpublic LoginSuccessHandler loginSuccessHandler(){return new LoginSuccessHandler();} }
    ServletInitializer.java

    [java] view plaincopyprint?
  • package?security;??
  • ??
  • import?javax.servlet.FilterRegistration;??
  • import?javax.servlet.ServletContext;??
  • import?javax.servlet.ServletException;??
  • ??
  • import?org.springframework.boot.builder.SpringApplicationBuilder;??
  • import?org.springframework.boot.web.support.SpringBootServletInitializer;??
  • import?org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter;??
  • ??
  • public?class?ServletInitializer?extends?SpringBootServletInitializer?{??
  • ??
  • ????@Override??
  • ????protected?SpringApplicationBuilder?configure(SpringApplicationBuilder?application)?{??
  • ????????return?application.sources(MainApplication.class);??
  • ????}??
  • ??????
  • ????@Override??
  • ????public?void?onStartup(ServletContext?servletContext)??
  • ????throws?ServletException?{??
  • ?????FilterRegistration.Dynamic?openEntityManagerInViewFilter?=?servletContext.addFilter("openEntityManagerInViewFilter",?OpenEntityManagerInViewFilter.class);??
  • ?????????openEntityManagerInViewFilter.setInitParameter("entityManagerFactoryBeanName","entityManagerFactory");??
  • ?????????openEntityManagerInViewFilter.addMappingForUrlPatterns(null,?false,?"/*");??
  • ????super.onStartup(servletContext);??
  • ????}??
  • }??
  • package security;import javax.servlet.FilterRegistration; import javax.servlet.ServletContext; import javax.servlet.ServletException;import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter;public class ServletInitializer extends SpringBootServletInitializer {@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder application) {return application.sources(MainApplication.class);}@Overridepublic void onStartup(ServletContext servletContext)throws ServletException {FilterRegistration.Dynamic openEntityManagerInViewFilter = servletContext.addFilter("openEntityManagerInViewFilter", OpenEntityManagerInViewFilter.class);openEntityManagerInViewFilter.setInitParameter("entityManagerFactoryBeanName","entityManagerFactory");openEntityManagerInViewFilter.addMappingForUrlPatterns(null, false, "/*");super.onStartup(servletContext);} }
    還有主類需要修改

    [java] view plaincopyprint?
  • package?security;??
  • import?java.io.IOException;??
  • import?java.util.HashMap;??
  • import?java.util.List;??
  • import?java.util.Map;??
  • import?java.util.Set;??
  • ??
  • import?javax.annotation.PostConstruct;??
  • ??
  • import?org.slf4j.Logger;??
  • import?org.slf4j.LoggerFactory;??
  • import?org.springframework.beans.factory.annotation.Autowired;??
  • import?org.springframework.boot.SpringApplication;??
  • import?org.springframework.boot.autoconfigure.EnableAutoConfiguration;??
  • import?org.springframework.boot.autoconfigure.SpringBootApplication;??
  • import?org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;??
  • import?org.springframework.web.method.HandlerMethod;??
  • import?org.springframework.web.servlet.mvc.method.RequestMappingInfo;??
  • import?org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;??
  • import?security.entity.SysResource;??
  • import?security.service.SResourceService;??
  • import?csecurity.service.UserService;??
  • import?security.support.MySecurityFilter;??
  • ??
  • @SpringBootApplication??
  • @EnableAutoConfiguration(exclude?=?MyFilterSecurityInterceptor.class)?//注意??
  • public?class?MainApplication{??
  • ??????
  • ????@Autowired??
  • ????private?SResourceService?sresourceService;??
  • ??????
  • ????private?static?final?Logger?log?=?LoggerFactory.getLogger(MainApplication.class);??
  • ????@PostConstruct??
  • ?????public?void?initApplication()?throws?IOException?{??
  • ?????????log.info("Running?with?Spring?profile(s)?:?{}");???
  • ????}??
  • ???????
  • ????public?static?void?main(String[]?args)?{??
  • ????????//SpringApplication.run(MainApplication.class,?args);??
  • ????????SpringApplication?app=new?SpringApplication(MainApplication.class);???????
  • ????????Appctx.ctx=app.run(args);??
  • ????????/*UserService?suserService?=?(UserService)?Appctx.ctx.getBean("suserService");?
  • ????????SysUser?su=?suserService.findByName("user");?
  • ????????System.out.println("密碼"+su.getPassword());?
  • ????????System.out.println("名字"+su.getName());?
  • ????????BCryptPasswordEncoder?bc=new?BCryptPasswordEncoder(4);//將密碼加密?
  • ????????su.setPassword(bc.encode(su.getPassword()));?
  • ????????System.out.println("密碼"+su.getPassword());?
  • ????????suserService.update(su);*/??
  • }??
  • }??
  • package security; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set;import javax.annotation.PostConstruct;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import security.entity.SysResource; import security.service.SResourceService; import csecurity.service.UserService; import security.support.MySecurityFilter;@SpringBootApplication @EnableAutoConfiguration(exclude = MyFilterSecurityInterceptor.class) //注意 public class MainApplication{@Autowiredprivate SResourceService sresourceService;private static final Logger log = LoggerFactory.getLogger(MainApplication.class);@PostConstructpublic void initApplication() throws IOException {log.info("Running with Spring profile(s) : {}"); }public static void main(String[] args) {//SpringApplication.run(MainApplication.class, args);SpringApplication app=new SpringApplication(MainApplication.class); Appctx.ctx=app.run(args);/*UserService suserService = (UserService) Appctx.ctx.getBean("suserService");SysUser su= suserService.findByName("user");System.out.println("密碼"+su.getPassword());System.out.println("名字"+su.getName());BCryptPasswordEncoder bc=new BCryptPasswordEncoder(4);//將密碼加密su.setPassword(bc.encode(su.getPassword()));System.out.println("密碼"+su.getPassword());suserService.update(su);*/ } }
    至此,我們spring security4就集成成功了,代碼,博主已經(jīng)驗證,如有什么錯誤的地方,歡迎提出。謝謝!
    還有資源表中的url可以使用spring的RequestMappingHandlerMapping類自動掃描入庫,具體請見http://blog.csdn.net/code__code/article/details/53886912。

    總結(jié)

    以上是生活随笔為你收集整理的Spring boot+Spring Security 4配置整合实例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    91丨九色丨高潮丰满 | 亚洲视频在线视频 | 久草电影免费在线观看 | 国产精品免费观看网站 | 久久高清视频免费 | 8x成人免费视频 | 69精品久久久 | 久久视频二区 | 麻豆国产网站 | 国产精品99久久久精品免费观看 | 狠狠色丁香婷婷综合久小说久 | 中文字幕有码在线 | 国产中年夫妇高潮精品视频 | 亚洲另类视频 | 国产中文字幕在线 | 国产99久久九九精品免费 | 国产在线v | 美女黄频视频大全 | 日韩免费成人 | 国产精品久久久久久久久久99 | 黄av免费在线观看 | 日本精品一区二区三区在线观看 | 中文字幕一区在线观看视频 | 天堂在线免费视频 | 亚州av成人 | 久久大片| 亚洲香蕉视频 | a极黄色片 | 国产日产在线观看 | 亚洲天堂在线观看完整版 | 亚洲成a人片77777kkkk1在线观看 | 国产中文在线视频 | 伊人黄 | 99精品国产福利在线观看免费 | 国产成人一二片 | 一区二区三区国产欧美 | 最新日韩在线观看 | 美女免费视频黄 | 免费在线日韩 | 91丨九色丨国产在线 | 中文成人字幕 | 精品不卡av| 91麻豆精品国产自产 | 国产美女免费观看 | 天天玩夜夜操 | 91色亚洲 | 精品二区视频 | 蜜臀aⅴ国产精品久久久国产 | 天天干天天摸天天操 | 久久国产精品影视 | 国产在线播放一区二区 | 国产淫a| 欧美色精品天天在线观看视频 | 久久久久免费电影 | 成人黄色电影在线 | 色婷婷色 | 久久五月激情 | 亚州av一区 | 久久精品中文字幕 | 天天躁日日躁狠狠躁 | 337p西西人体大胆瓣开下部 | 久久精精品视频 | 国产精品va在线播放 | 99婷婷| av福利在线看 | 中文字幕av在线不卡 | bbbbb女女女女女bbbbb国产 | 日韩精品免费在线观看 | 久久视频在线看 | 国产精品一区免费在线观看 | 一级片视频免费观看 | 91看片在线 | 中文字幕一区二区三区在线播放 | 超碰97在线人人 | 超级av在线| 麻花天美星空视频 | 天天操天天干天天综合网 | 黄色录像av| 国产激情免费 | 99在线精品观看 | 日韩深夜在线观看 | 国产精品久久久久av | 99成人免费视频 | 国内免费久久久久久久久久久 | 91中文字幕在线 | 天天操天天射天天 | 三上悠亚一区二区在线观看 | 色视频在线看 | 毛片基地黄久久久久久天堂 | 在线观看亚洲电影 | 丁香六月激情 | 精品国产乱码一区二 | 91精品在线视频观看 | 日韩性xxx | 亚洲综合在线发布 | 欧美国产三区 | 国产一级精品视频 | 日韩激情视频在线观看 | 免费在线观看污网站 | 中文字幕有码在线观看 | 亚洲精品国产精品99久久 | 亚州成人av在线 | 一区二区视| 青草视频在线免费 | 91av视频在线观看免费 | 午夜视频不卡 | 探花在线观看 | 探花视频在线观看 | 久久99日韩| 亚洲视频综合在线 | 夜夜躁日日躁狠狠久久av | 免费视频黄 | 狠狠的干狠狠的操 | 日韩偷拍精品 | 欧美午夜一区二区福利视频 | 亚洲精品在线观看免费 | 亚洲免费色 | 色网站在线观看 | 97免费中文视频在线观看 | 在线观看国产亚洲 | 亚洲欧美成aⅴ人在线观看 四虎在线观看 | 特级西西www44高清大胆图片 | 国产亚洲精品久久久久久久久久久久 | 国产精品久久久久久久7电影 | 久草在 | 91九色精品| 超碰国产在线播放 | 黄色亚洲| 成av在线 | 又粗又长又大又爽又黄少妇毛片 | 超级碰碰视频 | 国产精品男女啪啪 | 成人毛片在线视频 | 激情久久婷婷 | 欧美特一级 | 最近的中文字幕大全免费版 | 久久高清视频免费 | 亚洲精品久久久久久久不卡四虎 | 干干夜夜 | 久久99视频精品 | 在线观看色网 | 久久国产福利 | 亚洲一区日韩精品 | 在线综合 亚洲 欧美在线视频 | 91精品视频免费观看 | 色偷偷97 | 亚洲欧洲一区二区在线观看 | 国产色啪| 日韩一级精品 | 黄网av在线 | 97福利在线观看 | 草久中文字幕 | 最近乱久中文字幕 | 国产亚洲综合性久久久影院 | 免费在线色 | 91九色国产视频 | 国产黄色片免费 | 亚洲性xxxx | 成人一级片在线观看 | 欧美一级性生活片 | 亚洲精品午夜一区人人爽 | 久久国产系列 | 日韩视频区 | 国产精品a级 | 国产成人精品999在线观看 | 国产成人av网 | av中文字幕网站 | 中文字幕在线观看免费 | 亚洲视频第一页 | 女女av在线 | 久久久91精品国产一区二区三区 | 九热精品 | 欧美精品亚洲精品 | 国产精品成人av电影 | 国产精品激情 | 公与妇乱理三级xxx 在线观看视频在线观看 | 久久草精品 | 亚洲精品视频在线免费播放 | 99久久99久久精品国产片 | 国产美女在线观看 | 精品国产乱码一区二区三区在线 | 操操操日日日干干干 | 2021av在线 | 国产精品a成v人在线播放 | 久久久一本精品99久久精品66 | 日日夜夜天天 | 999一区二区三区 | 丁香婷婷激情啪啪 | 欧美在线aaa | 国产精品久久久久久久久久ktv | 91桃花视频 | 97国产一区| 国产成人精品一区在线 | 久久视频在线 | 婷婷在线综合 | 国产伦理精品一区二区 | 免费在线观看中文字幕 | 天天天综合| 午夜丁香网 | 91av免费在线观看 | 天天色综合天天 | 91精彩视频 | 欧美日韩在线精品一区二区 | 高清不卡毛片 | 久久在草 | 日韩一区二区三区高清在线观看 | 国产精品欧美一区二区三区不卡 | 中文字幕在线一区观看 | 亚洲人成免费网站 | 日韩精品高清视频 | 日韩精品在线观看av | 午夜视频99 | 黄色app网站在线观看 | 91在线永久 | 中文字幕观看av | 91精品啪| 免费黄色网址大全 | 日韩大片在线免费观看 | 成人免费看片98欧美 | 国产精品精品久久久久久 | 黄在线免费看 | 日韩av成人在线观看 | 亚洲最新av网址 | 美女国内精品自产拍在线播放 | 国产99免费 | 国产高清视频在线播放一区 | 涩涩成人在线 | 久久久亚洲精品 | 夜夜躁狠狠躁日日躁 | 日日夜夜添| 色激情在线| 国产在线视频不卡 | 国产一级二级三级视频 | 91视频91自拍 | 国产生活一级片 | 91精品国产欧美一区二区 | 婷婷色综合网 | 日韩av中文字幕在线 | 4438全国亚洲精品观看视频 | 久久这里只有精品久久 | 91精品第一页 | 久久精品一二三区 | 欧美福利片在线观看 | 国产精品国产三级国产aⅴ无密码 | 亚洲亚洲精品在线观看 | 日韩精品一区二区在线观看视频 | 国内精品久久久久久久久 | 在线看一级片 | 欧美二区三区91 | 久久久在线观看 | 天天操狠狠操 | 中文字幕乱码电影 | 丁香婷婷社区 | 亚洲毛片在线观看. | 国产福利精品在线观看 | 午夜久久久久 | 在线精品视频免费观看 | 亚洲天天草 | 亚洲午夜久久久久 | av在线收看| 国产又粗又猛又爽又黄的视频先 | 色综合 久久精品 | 中文字幕第一页在线视频 | 99热精品久久 | 国产很黄很色的视频 | 中文字幕在线观看第一页 | 国产一级免费播放 | 六月丁香激情综合色啪小说 | 人人爽人人爽人人爽人人爽 | 黄网站免费看 | 欧美精品一区二区在线播放 | 国产在线一区二区 | 亚洲 综合 专区 | 精品国产乱码一区二区三区在线 | 日韩免费视频一区二区 | 正在播放 国产精品 | 亚洲欧洲精品视频 | 久久精品国产一区二区三区 | 在线看毛片网站 | 国产看片免费 | 久久综合亚洲鲁鲁五月久久 | 日韩精品aaa| 久久久久久毛片精品免费不卡 | 免费a视频在线 | 色在线视频网 | 亚洲精品美女久久久久 | 91精品秘密在线观看 | 成人av在线直播 | 91九色在线观看视频 | 欧美一级日韩三级 | 西西www4444大胆视频 | 91久草视频 | 久久久黄色免费网站 | 精品美女国产在线 | 国产香蕉久久 | 国产精品毛片一区视频播 | 精品成人网 | 日韩中文字幕免费视频 | avlulu久久精品 | 免费在线观看黄 | 国产精品va在线观看入 | 国产爽妇网 | 热久久视久久精品18亚洲精品 | 免费一级片在线 | 日韩免费网址 | 欧美人人爱| 国产高清在线永久 | 丰满少妇麻豆av | 国模精品一区二区三区 | 精品久久久久久亚洲综合网站 | 久久久一本精品99久久精品66 | 日韩av资源在线观看 | 日韩 精品 一区 国产 麻豆 | 亚洲一区二区三区在线看 | 超碰夜夜 | av免费试看| 国产不卡视频在线 | 色婷婷精品大在线视频 | 欧美另类网站 | 国产视频午夜 | 手机成人免费视频 | 国产精品99久久久久的智能播放 | 国产视频中文字幕 | 福利视频导航网址 | 日韩欧美在线视频一区二区三区 | 亚洲精品自拍视频在线观看 | 天天干天天射天天插 | 粉嫩一区二区三区粉嫩91 | 欧美亚洲另类在线视频 | 韩国av电影在线观看 | 亚洲一级久久 | 国产黄色免费 | 日韩在线精品一区 | 91av小视频 | 国产精品18久久久久白浆 | av大片网站 | 色综合五月天 | 亚洲精品中文在线资源 | 91精品视屏 | 亚洲国产成人久久 | 天天爱天天 | 日韩免费在线一区 | 久久久精品在线观看 | 日韩在线无| 视频一区二区免费 | 国产成人福利在线观看 | 成人91在线| 国产小视频精品 | 99热国产在线中文 | 综合激情婷婷 | 波多野结衣视频网址 | 免费日p视频 | 久久国产精品久久国产精品 | 97在线看| 久久综合色8888 | 99精品国产免费久久久久久下载 | 夜夜爽www| 在线观av| 99久久99精品 | 一区二区三区在线视频111 | 最近最新mv字幕免费观看 | 五月花丁香婷婷 | 91av视频免费在线观看 | 免费观看9x视频网站在线观看 | 成av人电影 | 天天曰 | 国产不卡片 | 热精品 | 一区二区欧美在线观看 | 国产日韩高清在线 | av不卡免费看 | 日韩欧美视频一区二区三区 | 狠狠狠色丁香婷婷综合久久五月 | 91久久精品一区二区三区 | 久久精品99久久久久久2456 | 91九色蝌蚪视频网站 | 久精品在线 | 成人免费在线观看电影 | 国产一级精品视频 | 亚洲午夜精品久久久久久久久久久久 | 国产精品原创 | 亚洲午夜久久久久久久久 | 国产在线高清精品 | 91av蜜桃| 国产精品久久久久久久av电影 | 欧美综合色在线图区 | 蜜臀av性久久久久av蜜臀三区 | 久久午夜羞羞影院 | 狠狠色狠狠色综合日日小说 | av片在线观看免费 | 天天草天天摸 | 亚洲欧美激情插 | 日韩首页 | 色视频在线免费观看 | 在线免费观看亚洲视频 | 免费观看性生交 | 精品免费久久久久久 | 91精品久久久久久久久 | 中文在线字幕免费观看 | 日日夜操 | 日韩精品一区二区三区在线视频 | 人人干狠狠干 | 国产高清小视频 | 最新中文字幕 | 亚洲国产日韩欧美在线 | 亚洲精品视频第一页 | 日韩字幕在线观看 | 在线观看视频你懂 | 福利一区在线 | 久久久片 | 狠狠色噜噜狠狠狠合久 | 中文在线字幕免 | 午夜精品导航 | 国产一性一爱一乱一交 | 四虎在线影视 | 成人黄性视频 | 国产亚洲精品久久久久5区 成人h电影在线观看 | 在线观看中文字幕第一页 | 国产一级片免费播放 | 91精品国产自产老师啪 | 久久久久久综合网天天 | 日韩免费在线观看 | 亚洲精品黄色 | 成年人免费在线播放 | 婷婷国产v亚洲v欧美久久 | 最新av在线播放 | 黄色a三级 | 91最新网址在线观看 | 久久国产精品一区二区三区四区 | 国产剧情在线一区 | 99九九99九九九视频精品 | 天天操天天色天天 | 狠狠久久综合 | 探花视频在线观看免费版 | 中文字幕欧美激情 | 69国产精品视频 | 国产专区日韩专区 | 美女视频黄色免费 | 99久久99久久精品国产片果冰 | 五月激情亚洲 | 日批视频国产 | 久久久久亚洲精品成人网小说 | 99久久er热在这里只有精品66 | 黄色一级在线视频 | 国产中文伊人 | 国产精品人成电影在线观看 | 久久精品中文字幕一区二区三区 | 久久久久99精品国产片 | 国产最新精品视频 | 欧美乱码精品一区二区 | 极品久久久久 | 色播激情五月 | 久久官网 | 久久综合久久综合九色 | 国产精品久久久久久久久免费 | 久久九九网站 | 国产精品原创av片国产免费 | 五月天久久久久 | 国产欧美精品一区二区三区四区 | 国产98色在线 | 日韩 | 日日摸日日添夜夜爽97 | 亚洲精品91天天久久人人 | 又黄又刺激 | 亚洲,国产成人av | 天天天天天天天天操 | 69精品在线 | va视频在线 | 超碰97在线资源 | 日韩欧美国产激情在线播放 | 成人影片在线播放 | 成人午夜电影网 | 99中文字幕 | 91精品久久久久久粉嫩 | 成人性生交大片免费观看网站 | 免费黄色网址网站 | 香蕉视频在线免费看 | 六月丁香在线观看 | 波多野结衣精品视频 | 欧美精品久久久久久久久久久 | 在线观看 国产 | 久久欧洲视频 | 久久国产日韩 | 97精产国品一二三产区在线 | 四虎影视久久久 | 亚洲精选国产 | 亚洲精品99久久久久中文字幕 | 久久久免费电影 | www.狠狠干| 在线视频精品播放 | 在线视频久久 | 国产精品久久久久久久久久妇女 | 一本一本久久a久久精品综合小说 | 超碰精品在线 | 中文字幕亚洲国产 | 国内精品久久影院 | 亚洲精品tv久久久久久久久久 | 色香蕉网| 国产做aⅴ在线视频播放 | 一区二区欧美在线观看 | 豆豆色资源网xfplay | 91精品欧美一区二区三区 | 国产v在线播放 | 久久免费视频在线 | 麻豆成人小视频 | 国内外成人在线 | 成年人av在线播放 | 成人97人人超碰人人99 | 国产精品11| 国产精品午夜免费福利视频 | 久久成人精品电影 | www.香蕉视频在线观看 | 天天干天天操天天做 | 日韩一级片观看 | 97在线公开视频 | 中文字幕亚洲字幕 | 久草视频在线免费 | 日本中文一级片 | 特级毛片在线 | 国产剧情久久 | 亚洲va男人天堂 | aaa免费毛片 | 国产一级二级在线观看 | 香蕉视频日本 | 狠狠做深爱婷婷综合一区 | www.久久99 | 日日干综合 | 亚洲少妇久久 | 欧美性生活小视频 | av黄色免费看 | 69视频国产| 日本爱爱片 | 久在线| 国产成人亚洲精品自产在线 | 99精品热视频只有精品10 | 五月天亚洲婷婷 | 中文在线a天堂 | 欧美成人区 | 五月婷亚洲 | 99精品免费久久久久久久久日本 | 国产99久久九九精品 | 成人av电影在线 | 午夜在线免费观看 | 婷婷播播网| 五月婷婷综合激情 | 久久a级片| 午夜美女av | 91中文字幕在线观看 | 国产精品中文字幕在线播放 | 麻豆视频观看 | 香蕉视频免费在线播放 | 婷婷五天天在线视频 | 久久手机在线视频 | 日日操网站 | 免费观看午夜视频 | 日韩一区正在播放 | 插婷婷 | 国产拍在线 | 激情av五月婷婷 | 日韩一区二区三区免费视频 | 国产精品18久久久久久不卡孕妇 | 91经典在线 | 涩涩网站在线播放 | 久久午夜精品视频 | 女人18毛片a级毛片一区二区 | 久久久久国产成人免费精品免费 | 国产精品永久免费视频 | 不卡的av在线播放 | 久久免费在线观看 | 96看片| av丝袜制服 | 视频成人| 97在线免费观看视频 | 国产又粗又长的视频 | 在线91视频 | 国产亚洲视频系列 | 日韩视频二区 | 97在线视| 国产精品毛片久久蜜 | 国产精品第三页 | 97精品国产91久久久久久久 | 日韩三级在线 | 玖玖在线观看视频 | 日韩成人精品在线观看 | 亚洲一级片在线观看 | 一区二区欧美激情 | 国产精品久久久久久久久蜜臀 | 成年人视频在线免费观看 | 中文不卡视频在线 | 激情五月婷婷丁香 | 国产精品乱码在线 | 丁香婷婷色综合亚洲电影 | 精品在线小视频 | 久久精品影片 | 日本大片免费观看在线 | 成年人在线免费视频观看 | 日韩一区正在播放 | 欧美激情综合五月色丁香 | 中文字幕av网站 | 国产精品乱码在线 | 99久高清在线观看视频99精品热在线观看视频 | 人人澡人 | 午夜精品一区二区三区在线观看 | 日韩在线视 | 五月婷婷电影网 | 99热精品国产一区二区在线观看 | 国产精品久久久久久久久久三级 | 国产精品免费一区二区三区在线观看 | 在线中文字幕一区二区 | www成人精品 | 国产在线va| 91色偷偷 | 在线精品国产 | 日韩精品在线视频 | 国产在线视频在线观看 | 91爱在线 | 国产婷婷色 | 日韩欧美一区二区在线 | 成人毛片网 | 91视频91色| 男女靠逼app | 四虎在线视频免费观看 | 91九色蝌蚪在线 | 亚洲成人精品在线 | 免费av看片 | 狠狠狠狠狠干 | 国产一级黄色电影 | 99精品欧美一区二区蜜桃免费 | 香蕉免费| 日一日操一操 | 亚洲一区二区三区毛片 | 久久婷婷一区 | 日本婷婷色 | 午夜12点| 国产成人一二三 | 成人精品影视 | 一区精品久久 | 精品一区欧美 | 国产高清中文字幕 | 欧美极度另类性三渗透 | www.91成人| 久久成人18免费网站 | 免费看黄电影 | 亚洲精品在线国产 | 婷婷丁香在线观看 | 亚洲v欧美v国产v在线观看 | 五月天丁香视频 | 国产午夜在线观看视频 | 91麻豆精品国产91久久久更新时间 | 又色又爽又黄高潮的免费视频 | 免费黄a | 亚洲国产片 | 久久免视频 | 久久精品国亚洲 | 一区二区三区精品在线视频 | 伊人春色电影网 | 91久久精品一区二区三区 | 中文字幕在线专区 | 亚洲伦理中文字幕 | 尤物97国产精品久久精品国产 | 中文字幕视频 | 三级黄色免费 | 97看片网 | 高潮久久久久久久久 | 日本中文字幕系列 | 欧美最猛性xxxxx免费 | 欧美成人精品在线 | 日日夜夜精品免费 | 国产香蕉视频在线观看 | 日韩免费成人 | 日韩欧美视频免费在线观看 | 99在线精品视频在线观看 | 国产丝袜网站 | 日本三级全黄少妇三2023 | 亚洲日本激情 | 成年人免费在线观看网站 | 色婷婷色 | 黄a网 | 久久久电影网站 | 久草在线一免费新视频 | 欧美一区影院 | 中文免费观看 | 中文字幕在线播放视频 | 国产又粗又硬又爽的视频 | 欧美大片在线观看一区 | 日韩视频在线播放 | 91在线麻豆 | 国产不卡在线看 | 99精品色 | 精品国产一区二区三区男人吃奶 | 色诱亚洲精品久久久久久 | 天天操天天舔天天干 | 一区二区三区免费在线观看视频 | 人交video另类hd | 日韩久久精品一区二区 | 中文字幕色婷婷在线视频 | 久久综合久色欧美综合狠狠 | 国产高清视频色在线www | 国产专区欧美专区 | 中文字幕电影网 | 免费观看日韩 | 亚洲精品视频在线观看免费视频 | 成人黄色大片 | 在线国产99| 国产精品久久久免费 | 国产在线v | 西西444www大胆高清图片 | 精品久久久一区二区 | 中文成人字幕 | 91福利影院在线观看 | 国产精品久久久久久久毛片 | 国内揄拍国内精品 | 国产伦精品一区二区三区在线 | 91九色老| 亚洲伊人av | 国产一区二区久久 | 热久精品 | 欧美性色黄大片在线观看 | 天天射天天干天天操 | 中文在线免费看视频 | 国产在线观看污片 | 国产一区二区三区午夜 | 四虎影视成人永久免费观看亚洲欧美 | 五月婷婷在线视频观看 | 亚洲精品国产自产拍在线观看 | 777久久久 | 狠狠插狠狠操 | 在线观看视频福利 | 精品久久一区 | 久久免费高清 | 欧美日韩一区二区三区视频 | 欧美污污网站 | 国产玖玖精品视频 | 91亚洲综合 | 狠狠色狠狠色综合日日小说 | 丁香婷婷综合网 | 婷婷色网视频在线播放 | 91精品国产成人 | 国产成a人亚洲精v品在线观看 | 81国产精品久久久久久久久久 | 国产一区二区三区免费视频 | 日韩综合视频在线观看 | 婷婷综合五月天 | 欧美日韩免费一区二区 | 国产又粗又猛又爽又黄的视频免费 | 欧美日韩免费观看一区=区三区 | 狠狠色综合网站久久久久久久 | av九九 | aaa亚洲精品一二三区 | 欧美国产日韩一区二区三区 | 亚洲情婷婷 | 蜜臀aⅴ国产精品久久久国产 | 日韩在线大片 | 国产精品国产精品 | 香蕉影院在线播放 | www狠狠操 | 久章草在线观看 | 麻豆精品传媒视频 | 狠狠干狠狠久久 | 日韩欧美视频免费在线观看 | 国产精品久久久久久一区二区三区 | 成年人在线免费看视频 | 午夜精品福利一区二区 | 在线观看中文字幕一区二区 | a视频在线观看免费 | 一区中文字幕电影 | 久久夜夜爽 | 欧美大香线蕉线伊人久久 | 国产精品黄网站在线观看 | 亚洲最新视频在线 | 日本中文一级片 | 亚洲在线成人精品 | 日本不卡123 | 久久人人干 | 国产精品精 | av片子在线观看 | 国产一级片免费视频 | 欧美日韩亚洲第一页 | 九九九热视频 | 免费三级大片 | 久久久国产一区二区三区四区小说 | 一级黄色电影网站 | 精品国产一区二区三区在线 | 草久在线 | 在线观看中文字幕2021 | 亚洲最新视频在线 | 97超碰资源总站 | 视频一区在线播放 | 美女又爽又黄 | 黄a网站 | 成人在线播放免费观看 | 成人亚洲精品国产www | 一级理论片在线观看 | 亚洲视频1区2区 | 欧美激情第八页 | www久久精品| 国产精品黄网站在线观看 | 97日日碰人人模人人澡分享吧 | 麻豆国产露脸在线观看 | 婷婷精品在线 | 91九色网址| 欧美精品午夜 | 国产综合在线观看视频 | 波多野结衣在线播放视频 | 一级黄色免费网站 | 69亚洲视频 | 日本久久久影视 | 国产伦精品一区二区三区照片91 | 久久亚洲国产精品 | 99久久婷婷国产综合精品 | av免费看在线 | 国产一线天在线观看 | 亚洲成人精品av | 亚洲精品久久激情国产片 | 欧美性网站 | 69热国产视频 | 日韩中文字幕视频在线 | 欧美精品乱码久久久久久 | 超碰在线人人爱 | 又爽又黄又无遮挡网站动态图 | 亚洲激情一区二区三区 | 美女很黄免费网站 | 国产区精品视频 | 少妇bbw撒尿 | 久久免费精品国产 | 久久成人亚洲欧美电影 | 欧美久久影院 | 中文字幕色婷婷在线视频 | 亚洲国产人午在线一二区 | 国产小视频国产精品 | 九九九九热精品免费视频点播观看 | 久久久精品网站 | 天天射网 | 日韩国产精品久久 | 在线观看一区二区精品 | 国产无遮挡猛进猛出免费软件 | 国产黄色大片 | 亚洲欧美日韩国产一区二区三区 | 国产1区2区3区精品美女 | 91精品免费在线视频 | 亚州国产视频 | 精品人人爽| 久久高清 | 少妇高潮流白浆在线观看 | 狠狠久久婷婷 | 色婷婷亚洲综合 | 欧美xxxx性xxxxx高清 | 国产三级视频 | 久久久久影视 | 国产一区二区在线免费观看 | 色久五月 | 国内精品视频久久 | 成人中心免费视频 | 日日干夜夜爱 | 国产精品福利一区 | 特级黄色视频毛片 | 久久久久久久毛片 | 国产精品3| 日韩mv欧美mv国产精品 | 免费黄在线看 | 国产美女精品人人做人人爽 | 日日碰狠狠躁久久躁综合网 | 808电影免费观看三年 | 国产精品99久久久久久有的能看 | 最近免费中文字幕 | 色先锋资源网 | 99免费国产| 国产91电影在线观看 | 91亚洲精品在线观看 | 婷婷激情网站 | 六月婷婷久香在线视频 | 91看片在线观看 | 欧美日韩在线免费观看 | av在线官网 | 六月丁香久久 | 亚洲精品自拍视频在线观看 | 最近日本字幕mv免费观看在线 | 精品视频久久久久久 | 久久国产欧美日韩精品 | 操操操人人 | 热久久免费国产视频 | 亚洲国产精品免费 | 欧美激情xxxx | 日本久久久久久科技有限公司 | 国产精国产精品 | 一区二区三区四区影院 | 最新日韩视频在线观看 | 一区二区三区免费在线观看视频 | 日韩网站免费观看 | www.久久久com | 国产亚洲精品久久久久5区 成人h电影在线观看 | 在线观看涩涩 | 黄色大全免费网站 | 精壮的侍卫呻吟h | 色婷婷丁香 | 精品国产一区二区在线 | 最近中文字幕大全 | 久久a v电影 | 中文字幕永久在线 | 国产剧情一区二区在线观看 | 久久久久黄色 | 91精品一区国产高清在线gif | 91色在线观看 | 精品一区二区三区久久 | 久久影视精品 | 国产手机在线 | 99在线精品免费视频九九视 | 亚洲精品动漫成人3d无尽在线 | 精品久久久久久久久亚洲 | 天天躁日日躁狠狠躁 | 日韩欧美视频在线免费观看 | 成人午夜剧场在线观看 | 国产黄色一级片 | 亚洲va在线va天堂 | 色全色在线资源网 | 国产视频美女 | 色999视频 | 色天天久久 | 精品在线你懂的 | 午夜精品一区二区国产 | 天天操天天爽天天干 | 久久黄色a级片 | 久久精品日产第一区二区三区乱码 | 国产粉嫩在线观看 | 婷婷黄色片 | 国色天香第二季 | 欧美色综合天天久久综合精品 | 成人sm另类专区 | 国产黄大片在线观看 | 亚洲日本中文字幕在线观看 | 国产一区视频免费在线观看 | a在线免费 | 免费高清男女打扑克视频 | 182午夜在线观看 | 国产黑丝袜在线 | 亚洲 中文 欧美 日韩vr 在线 | 日本精品一 | 日韩二区在线 | 97人人添人澡人人爽超碰动图 | 久久久久久久久久久高潮一区二区 | 久久中文精品视频 | 国产高清精 | 日韩丝袜 | 国产一区二区精品在线 | 国产专区在线看 | 亚洲人在线7777777精品 | 久久精品网站免费观看 | 最新av网址在线观看 | 日日日操操 | 国产三级午夜理伦三级 | 精品极品在线 | 成人黄色小说网 | 欧美一区二区三区在线播放 | 欧美激情va永久在线播放 | 国产精品自产拍在线观看桃花 | 色窝资源| 亚洲一区二区三区四区在线视频 | 亚洲欧美视频网站 | 最新色视频| 91在线精品观看 | 国产伦理久久精品久久久久_ | 99久国产| 国产精品一区二区白浆 | 欧美日韩不卡一区二区三区 | 亚洲精品国内 | 91视频免费 | 天天人人 | 日韩午夜电影网 | 黄色福利网 | 天天综合成人 | 久久视频免费在线观看 | 欧美日性视频 | 精品一二区 | av电影免费在线播放 | 日韩精品一区二区在线视频 | 欧美精品一区二区免费 | 免费av电影网站 | 999抗病毒口服液 | 99精品视频免费看 | 久久96国产精品久久99软件 | 四虎成人网 | 天天草天天 | a级片韩国 | 久久草| 久久桃花网 | 88av视频| 日韩亚洲国产中文字幕 | 久久精品亚洲 | 国内精品久久久久影院优 | 国产午夜免费视频 | 久久精品国产一区二区三 | 国产一级片毛片 | 五月婷婷视频在线观看 | 在线观看的av网站 | 丁香在线视频 | 日韩av影片在线观看 | 国产理论一区二区三区 | 男女啪啪网站 | 国产老太婆免费交性大片 |