日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringSecurity的简单使用使用案列说明

發布時間:2024/4/15 javascript 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringSecurity的简单使用使用案列说明 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

SpringSecurity

Spring Security是 Spring提供的安全認證服務的框架。 使用Spring Security可以幫助我們來簡化認證
和授權的過程。官網:https://spring.io/projects/spring-security
認證:識別每一次請求是誰在發起
授權:鑒別某個功能或數據,當前用戶是否有權限訪問

RBAC是什么?

RBAC 是基于角色的訪問控制(Role-Based Access Control )在 RBAC 中,權限與角色相關聯,用戶通過成為適當角色的成員而得到這些角色的權限。這就極大地簡化了權限的管理。這樣管理都是層級相互依賴的,權限賦予給角色,而把角色又賦予用戶,這樣的權限設計很清楚,管理起來很方便。

權限模塊數據模型(表的設計)

授權過程:用戶必須完成認證之后才可以進行授權,首先可以根據用戶查詢其角色,再根據角色查詢對應的菜單,這樣就確定了用戶能夠看到哪些菜單。然后再根據用戶的角色查詢對應的權限,這樣就確定了用戶擁有哪些權限。
要實現最終的權限控制,需要有一套表結構支撐:
用戶表t_user、權限表t_permission、角色表t_role、菜單表t_menu、用戶角色關系表t_user_role、角
色權限關系表t_role_permission、角色菜單關系表t_role_menu。
表之間關系如下圖:

搭建maven項目

pom.xml

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.fs</groupId><artifactId>Spring-Security-Demo</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><!-- 集中定義依賴版本號 --><properties><!-- 指定編譯字符集,jdk版本--><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies> <!-- 導入springMVC的 依耐--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.5.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.0.5.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.0.5.RELEASE</version></dependency><!-- 導入spring-security的依耐--><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-web</artifactId><version>5.0.5.RELEASE</version></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId><version>5.0.5.RELEASE</version></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-taglibs</artifactId><version>5.0.5.RELEASE</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><configuration><!-- 指定端口 --><port>89</port><!-- 請求路徑 --><path>/</path></configuration></plugin></plugins></build> </project>

web.xml

注意事項:
DelegatingFilterProxy用于整合第三方框架
整合Spring Security時過濾器的名稱必須為springSecurityFilterChain,
否則會拋出NoSuchBeanDefinitionException異常
在web.xml中主要配置SpringMVC的DispatcherServlet和用于整合第三方框架的
DelegatingFilterProxy,用于整合Spring Security。

<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><filter><!--DelegatingFilterProxy用于整合第三方框架整合Spring Security時過濾器的名稱必須為springSecurityFilterChain,否則會拋出NoSuchBeanDefinitionException異常--><filter-name>springSecurityFilterChain</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class></filter><filter-mapping><filter-name>springSecurityFilterChain</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- 加載spring 的容器--><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- 指定加載的配置文件 ,通過參數contextConfigLocation加載 --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-security.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping> </web-app>

spring-security.xml

在spring-security.xml中主要配置Spring Security的攔截規則和認證管理器。
我們真實生產環境還差很遠,還存在如下一些問題:
1、項目中我們將所有的資源(所有請求URL)都保護起來,實際環境下往往有一些資源不需要認證也可以訪問,也就是可以匿名訪問。
2、登錄頁面是由框架生成的,而我們的項目往往會使用自己的登錄頁面。
3、直接將用戶名和密碼配置在了配置文件中,而真實生產環境下的用戶名和密碼往往保存在數據庫中。
4、在配置文件中配置的密碼使用明文,這非常不安全,而真實生產環境下密碼需要進行加密。本章節需要對這些問題進行改進。

配置可匿名訪問的資源
第一步:在項目中創建pages目錄,在pages目錄中創建a.html和b.html
第二步:在spring-security.xml文件中配置,指定哪些資源可以匿名訪問
使用指定的登錄頁面
第一步:提供login.html作為項目的登錄頁面
第二步:修改spring-security.xml文件,指定login.html頁面可以匿名訪問
第三步:修改spring-security.xml文件,加入表單登錄信息的配置

對密碼進行加密
前面我們使用的密碼都是明文的,這是非常不安全的。一般情況下用戶的密碼需要進行加密后再保存到
數據庫中。
常見的密碼加密方式有:
3DES、AES、DES:使用對稱加密算法,可以通過解密來還原出原始密碼
MD5、SHA1:使用單向HASH算法,無法通過計算還原出原始密碼,但是可以建立彩虹表進行查表破

bcrypt:將salt隨機并混入最終加密后的密碼,驗證時也無需單獨提供之前的salt,從而無需單獨處理
salt問題

加密后的格式一般為:$2a101010/bTVvqqlH9UiE0ZJZ7N2Me3RIgUCdgMheyTgV0B4cMCSokPa.6oCa
實現方法:在spring-security.xml文件中指定密碼加密對象

配置多種校驗規則
為了測試方便,首先在項目中創建a.html、b.html、c.html幾個頁面
修改spring-security.xml文件:

注解方式權限控制:使用場景多
提供的注解方式進行控制。
實現步驟:
第一步:在spring-security.xml文件中配置組件掃描,用于掃描Controller
第二步:在spring-security.xml文件中開啟權限注解支持
第三步:創建Controller類并在Controller的方法上加入注解進行權限控制

退出登錄
用戶完成登錄后Spring Security框架會記錄當前用戶認證狀態為已認證狀態,即表示用戶登錄成功了。
那用戶如何退出登錄呢?我們可以在spring-security.xml文件中進行配置:

通過配置可以發現,如果用戶要退出登錄,只需要請求/logout.do這個URL地址就可以,同時會
將當前session失效,最后頁面會跳轉到login.html頁面。

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:security="http://www.springframework.org/schema/security"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--開啟spring的包掃描--><context:component-scan base-package="com.fs"/> <!-- 開啟注解配置--><context:annotation-config/> <!-- 開啟mvc的注解--><mvc:annotation-driven/> <!-- 開啟注解方式的權限控制,不開啟默認是禁用--><security:global-method-security pre-post-annotations="enabled"/><!--http:用于定義相關權限控制,可以配置多個security:當設置為‘none’時,與pattern屬性匹配的請求將被Spring忽略安全。將不會應用任何安全過濾器,也不會提供任何SecurityContext。pattern:指定哪些資源不需要進行權限校驗,可以使用通配符 --><security:http security="none" pattern="/login.html"/><security:http security="none" pattern="/js/**" /><security:http security="none" pattern="/css/**" /><security:http security="none" pattern="/img/**" /><security:http security="none" pattern="/plugins/**" /> <!-- <security:http security="none" pattern="/pages/a.html"/>--> <!-- <security:http security="none" pattern="/pages/b.html"/>--> <!-- 使用通配符--> <!-- <security:http security="none" pattern="/pages/**"/>--><!--、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、--> <!--security:http標簽用于定義相關權限控制相關屬性auto-config:則默認為“false”。設置為true時,框架會提供一些配置,建議配置為true,可以進源碼查看注釋use-expressions:則默認為“true”.用于指定intercept-url中的access屬性是否使用表達式如果啟用時,每個屬性應該包含一個布爾表達式。如果表達式計算為“true”時,將授予訪問權限。 --><security:http auto-config="true" use-expressions="true"><!-- 配置多鐘校驗規則:security:intercept-url這個標簽isAuthenticated:只要認證通過就可以訪問index.jsphasAnyAuthority:擁有add或者find權限就可以訪問a.htmlhasRole:擁有ROLE_ADMIN角色就可以訪問b.html頁面--><security:intercept-url pattern="/index.html" access="isAuthenticated()"/><security:intercept-url pattern="/pages/a.html" access="hasAnyAuthority('add','find')"/><security:intercept-url pattern="/pages/b.html" access="hasRole('ROLE_ROOT')"/> <!-- 擁有ROLE_XIAOFU角色就可以訪問d.html頁面,注意:此處雖然寫的是XIAOFU角色,框架會自動加上前綴ROLE_--><security:intercept-url pattern="/pages/c.html" access="hasRole('XIAOFU')"/><!--security:intercept-url標簽:定義一個攔截規則屬性pattern:對哪些url進行權限控制,/**就是對所有的請求都進行權限控制access:在請求對應的url時需要什么權限,默認配置時,它應該是一個以逗號分隔的角色列表,當配置多個角色時,請求的用戶只需要有一個角色對應,就能成功訪問對應的url --> <!-- <security:intercept-url pattern="/**" access="hasRole('ROLE_ROOT')"/>--><security:intercept-url pattern="/**" access="hasAnyRole('ROLE_ROOT','ROLE_XIAOFU')"/><!--配置指定的登錄頁面訪問url,如果我們要使用我們自己指定的頁面作為登錄頁面.必須配置登錄表單url若我們不配置.會默認使用spring-security自帶的登錄權限頁面login-page:指定登錄頁面username-parameter="username" password-parameter="password" 指定收集表單提交的username和passwordlogin-processing-url: 表單提交的urldefault-target-url:身份驗證成功后將重定向到的URL,未指定,默認為應用程序的根目錄。authentication-failure-url:登錄失敗頁面的URL。如果沒有指定登錄失敗URL,則使用Spring安全性會自動創建一個失敗的登錄URL --><security:form-login login-page="/login.html"username-parameter="username"password-parameter="password"login-processing-url="/login.do"default-target-url="/index.html"authentication-failure-url="/login.html"/><!--csrf:對應CsrfFilter過濾器disabled:是否啟用CsrfFilter過濾器,如果使用自定義登錄頁面需要關閉此項,否則登錄操作會被禁用(403) --><security:csrf disabled="true"/><!--logout:退出登錄logout-url:退出登錄操作對應的請求路徑logout-success-url:退出登錄后的跳轉頁面invalidate-session:指定注銷是否也會導致HttpSession失效。如果未指定,則默認為true。--><security:logout logout-url="/logout.do"logout-success-url="/login.html"invalidate-session="true"/></security:http><!--security:authentication-manager:標簽認證管理器,用于處理認證操作 --><security:authentication-manager> <!--security:authentication-provider:標簽認證提供者,執行具體的認證邏輯user-service-ref: 指定實現UserDetailsService接口的實現類 --><security:authentication-provider user-service-ref="userService"><!--user-service:標簽用于獲取用戶信息,提供給authentication-provider進行認證 --><!--<security:user-service>security:user:標簽name:定義用戶信息,可以指定用戶名、密碼、角色,后期可以改為從數據庫查詢用戶信息password:{noop}標簽當前使用密碼明文authorities:授予用戶的多個權限之一。用逗號分隔這里我是配置死的,真正是從數據庫中查詢出來<security:user name="xiaofu" password="{noop}123" authorities="ROLE_XIAOFU"/></security:user-service>--><!-- 指定對密碼進行加密的對象.就是我們下面配置的加密對象--><security:password-encoder ref="passwordEncoder"/></security:authentication-provider></security:authentication-manager><!--把自定義實現UserDetailsService接口的實現類交給IOC管理--><bean id="userService" class="com.fs.service.UserService"/><!--對密碼進行加密,配置密碼加密對象,bcrypt:將salt隨機并混入最終加密后的密碼,驗證時也無需單獨提供之前的salt,從而無需單獨處理salt問--><bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/> </beans>

UserService

從數據庫查詢用戶信息(案列就使用集合模擬數據庫中角色權限數據)

如果我們要從數據庫動態查詢用戶信息,就必須按照spring security框架的要求提供一個實現
UserDetailsService接口的實現類,并按照框架的要求進行配置即可??蚣軙詣诱{用實現類中的方法
并自動進行密碼校驗。

我們提供了UserService實現類,并且按照框架的要求實現了UserDetailsService接口。在spring
配置文件中注冊UserService,指定其作為認證過程中根據用戶名查詢用戶信息的處理類。當我們進行
登錄操作時,spring security框架會調用UserService的loadUserByUsername方法查詢用戶信息,并
根據此方法中提供的密碼和用戶頁面輸入的密碼進行比對來實現認證操作。

package com.fs.service;import com.fs.pojo.Member; 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.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;/* 如果我們要從數據庫動態查詢用戶信息,就必須按照spring security框架的要求提供一個實現 UserDetailsService接口的實現類,并按照框架的要求進行配置即可。框架會自動調用實現類中的方法 并自動進行密碼校驗。*/public class UserService implements UserDetailsService {//注入密碼加密對象@Autowiredprivate BCryptPasswordEncoder passwordEncoder;/*** 重寫的方法,當用戶提交表單后會走這個方法,* @param username 表單提交的username* @return* @throws UsernameNotFoundException*/@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {System.out.println("用戶輸入的:"+username);//----------------------------------------模擬數據庫的數據-----------------------------------------------//模擬假數據,相當于這個數據是從Map<String, Object> memberMap = new HashMap<>();//明文密碼,沒有加密 // Member xiaofu = new Member("xiaofu", "123"); // Member member = new Member("root", "root");//使用BCryptPasswordEncoder對密碼進行加密Member xiaofu = new Member("xiaofu", passwordEncoder.encode("123"));Member member = new Member("root", passwordEncoder.encode("root"));memberMap.put(xiaofu.getUsername(),xiaofu);memberMap.put(member.getUsername(),member);//---------------------------------------------------------------------------------------//根據用戶名查詢數據庫的用戶信息(包含數據庫中存儲的密碼等user的所有的用戶信息)Member memberDB = (Member) memberMap.get(username);//判斷是否查出if (memberDB == null){//說明用戶不存在,spring安全框架拿到null后,說明沒有這個用戶,他就會跳轉到你設置的authentication-failure-urlreturn null;}else {/*將用戶信息返回框架,框架會進行密碼對比(頁面提交的密碼和數據庫中查詢的密碼進行對比)org.springframework.security.core.userdetails.User;這個對象是spring security提供的public User(String username, String password, Collection<? extends GrantedAuthority> authorities) {this(username, password, true, true, true, true, authorities);}有三個參數的構造方法,username:表單提交的usernamepassword:數據庫查詢出的登錄用戶對象的密碼authorities:數據庫查詢出的用戶權限的List集合(一個用戶有多個權限)*///模擬數據庫查詢出的權限List<GrantedAuthority> list = new ArrayList<>();//模擬添加兩個權限list.add(new SimpleGrantedAuthority("add"));//授權list.add(new SimpleGrantedAuthority("find"));//模擬當用戶名是root的時候添加一個角色,這個角色在配置文件中配置了的,只能這個角色才能有權限訪問// <security:intercept-url pattern="/**" access="hasRole('ROLE_ROOT')"/>if (username.equals("root")){list.add(new SimpleGrantedAuthority("ROLE_ROOT"));//授予角色ROLE_就表示角色}//模擬當前用戶使小付的時候添加角色if (username.equals("xiaofu")){list.add(new SimpleGrantedAuthority("ROLE_XIAOFU"));}//這是沒有加密需要在密碼前加{noop} // User securityUser = new User(username,"{noop}"+member.getPassword(),list);//使用BCryptPasswordEncoder加密后,就需要{noop}了User securityUser = new User(username,memberDB.getPassword(),list);//框架進行密碼進行校驗(頁面提交的密碼,與數據庫的密碼比對)return securityUser;}} }

Member實體會員類

package com.fs.pojo; /* 會員賬號密碼*/ public class Member {private String username;private String password;getset方法 }

HelloController(注解對方法實現權限控制)

package com.fs.controller;import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;@RestController @RequestMapping("/hello")//要在配置文件中配置這個路徑能被某個角色或者權限控制,否則403,<security:intercept-url pattern="/**" access="hasRole('ROLE_XIAOFU')"/> //@PreAuthorize("hasRole('ROLE_ROOT')")//表示這個類上中的方法只能ROLE_ROOT這個角色訪問 public class HelloController {@RequestMapping("/add")@PreAuthorize("hasAnyAuthority('add')")//表示訪問這個方法需要add權限才能調用這個方法public String add(){System.out.println("add...");return "add...ok";}@RequestMapping("/find")@PreAuthorize("hasAnyAuthority('find')")//表示訪問這個方法需要find權限才能調用這個方法public String find(){System.out.println("find...");return "find...ok";}@RequestMapping("/findOrAdd")@PreAuthorize("hasAnyAuthority('find','add')")//表示訪問這個方法需要add或者find權限才能調用這個方法public String findOrAdd(){System.out.println("findOrAdd...");return "findOrAdd...ok";}@RequestMapping("/role")@PreAuthorize("hasRole('ROLE_ROOT')")//表示訪問這個方法需要ROLE_ROOT這個角色才能訪問public String role(){System.out.println("role...");return "role...ok";} }

login.html,index.html,a.html,b.html,c.html

login.html

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>登錄頁面</title> </head> <body> <form action="/login.do" method="post">用戶名:<input type="text" name="username"><br>密碼:<input type="password" name="password"><br><input type="submit" value="登錄"> </form> </body> </html>

index.html

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> HelloWorld </body> </html>

a.html,b.html,c.html

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> a.html </body> </html>

測試

啟動tomcat發現,直接訪問任意頁面,都會跳轉到login.html,然后登錄(在UserService中使用list集合寫死了登錄用戶名的)后,就能根據這個用戶的角色權限去訪問sping-security配置文件中配置的權限對應的頁面或者@PreAuthorize注解對應的方法路徑

總結

以上是生活随笔為你收集整理的SpringSecurity的简单使用使用案列说明的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。