成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術(shù)文章
文章詳情頁

Spring Security 安全框架應(yīng)用原理解析

瀏覽:154日期:2023-06-28 13:40:49
Spring Security 簡介背景分析

企業(yè)中數(shù)據(jù)是最重要的資源,對于這些數(shù)據(jù)而言,有些可以直接匿名訪問,有些只能登錄以后才能訪問,還有一些你登錄成功以后,權(quán)限不夠也不能訪問.總之這些規(guī)則都是保護系統(tǒng)資源不被破壞的一種手段.幾乎每個系統(tǒng)中都需要這樣的措施對數(shù)據(jù)(資源)進行保護.我們通常會通過軟件技術(shù)對這樣業(yè)務(wù)進行具體的設(shè)計和實現(xiàn).早期沒有統(tǒng)一的標(biāo)準(zhǔn),每個系統(tǒng)都有自己獨立的設(shè)計實現(xiàn),但是對于這個業(yè)務(wù)又是一個共性,后續(xù)市場上就基于共享做了具體的落地實現(xiàn),例如Spring Security,Apache shiro誕生了.

認證授權(quán)分析

用戶在進行資源訪問時,要求系統(tǒng)要對用戶進行權(quán)限控制,其具體流程如圖所示:

Spring Security 安全框架應(yīng)用原理解析

Spring Security 概述

Spring Security 是一個企業(yè)級安全框架,由spring官方推出,它對軟件系統(tǒng)中的認證,授權(quán),加密等功能進行封裝,并在springboot技術(shù)推出以后,配置方面做了很大的簡化.市場上現(xiàn)在的分布式架構(gòu)下的安全控制正在逐步的轉(zhuǎn)向Spring Security.

Spring Security 基本架構(gòu)

Spring Security 在企業(yè)中實現(xiàn)認證和授權(quán)業(yè)務(wù)時,底層構(gòu)建了大量的過濾器.Spring Security 安全框架應(yīng)用原理解析其中:綠色部分為認證過濾器,需要我們自己配置,也可以配置過個認證過濾器.也可以使用Spring Security提供的默認認證過濾器.黃色部分為授權(quán)過濾器.Spring Security就是通過這些過濾器然后調(diào)用相關(guān)對象一起完成認證和授權(quán)操作.

Spring Security 快速入門

創(chuàng)建工程

Spring Security 安全框架應(yīng)用原理解析

添加項目依賴

<?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> <parent><artifactId>spring-boot-starter-parent</artifactId><groupId>org.springframework.boot</groupId><version>2.3.2.RELEASE</version> </parent> <groupId>com.cy</groupId> <artifactId>02-jt-spring-security</artifactId> <version>1.0-SNAPSHOT</version> <properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target> </properties> <dependencies><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId></dependency> </dependencies></project>

創(chuàng)建配置文件

在resources目錄下創(chuàng)建application.yml文件,并指定服務(wù)端口

server: port: 8080

創(chuàng)建項目啟動類

package com.cy.jt;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class SpringSecurityApplication { public static void main(String[] args) {SpringApplication.run(SpringSecurityApplication.class,args); }}

運行啟動類訪問測試

第一步:檢查控制輸出,是否自動生成了一個密碼,例如:

Using generated security password: 360123aa-df93-4cd9-bab4-5212af421d2c

第二步:打開瀏覽器輸入http://localhost:8080,然后呈現(xiàn)登錄頁面,例如:

Spring Security 安全框架應(yīng)用原理解析

在登錄窗口中輸入用戶名user(系統(tǒng)默認),密碼(服務(wù)啟動時,控制臺默認輸出的密碼),然后點擊Sign in進行登錄,登錄成功默認會出現(xiàn),如下界面:

Spring Security 安全框架應(yīng)用原理解析

定義登錄成功頁面

在項目的resources目錄下創(chuàng)建static目錄,并在此目錄創(chuàng)建一個index.html文件,例如:

<!DOCTYPE html><html lang='en'><head> <meta charset='UTF-8'> <title>Title</title></head><body> <h1>Login Ok</h1></body></html>

啟動服務(wù),再次進行登錄訪問測試,登錄成功以后系統(tǒng)默認會跳轉(zhuǎn)到index.html頁面,例如

Spring Security 安全框架應(yīng)用原理解析

配置登錄密碼

第一步:編寫一個方法(可以在啟動類中調(diào)用執(zhí)行),對一個名文進行加密,例如:

static void encodePwd(){BCryptPasswordEncoder encoder=new BCryptPasswordEncoder();String password='123456';//明文String newPwd=encoder.encode('123456');System.out.println(newPwd);//$2a$10$fahHJIe3SJm3KcyiPPQ2d.a2qR029gB3qKHrKanQ87u.KbtZ6Phr. }

第二步:將用戶和密碼在在springboot工程的application.yml文件中進行配置,例如:

spring: security: user: name: jack #password: 123456 #這種寫法,密碼太簡單了 password: ’{bcrypt}$2a$10$fahHJIe3SJm3KcyiPPQ2d.a2qR029gB3qKHrKanQ87u.KbtZ6Phr.’

其中,{bcrypt}指定了密碼加密時使用的算法

第三步:啟動服務(wù),重新進行登錄測試.

SpringSecurity 認證邏輯實現(xiàn)自定義登陸邏輯

SpringSecurity支持通過配置文件的方式定義用戶信息(賬號密碼和角色等),但這種方式有明顯的缺點,那就是系統(tǒng)上線后,用戶信息的變更比較麻煩。因此SpringSecurity還支持通過實現(xiàn)UserDetailsService接口的方式來提供用戶認證授權(quán)信息,其應(yīng)用過程如下:第一步:定義security配置類,例如:

/** * 由@Configuration注解描述的類為spring中的配置類,配置類會在spring * 工程啟動時優(yōu)先加載,在配置類中通常會對第三方資源進行初始配置. */@Configurationpublic class SecurityConfig { /** * 定義SpringSecurity密碼加密對象 * @Bean 注解通常會在@Configuration注解描述的類中描述方法, * 用于告訴spring框架這個方法的返回值會交給spring管理,并spring * 管理的這個對象起個默認的名字,這個名字與方法名相同,當(dāng)然也可以通過 * @Bean注解起名字 */ @Bean //對象名默認為方法名 //@Bean('bcryptPasswordEncoder')//bean對象名字為bcryptPasswordEncoder public BCryptPasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder(); }}

第二步:定義UserDetailService接口實現(xiàn)類,自定義登陸邏輯,代碼如下:UserDetailService為SpringSecurity官方提供的登錄邏輯處理對象,我們自己可以實現(xiàn)此接口,然后在對應(yīng)的方法中進行登錄邏輯的編寫即可.

package com.cy.jt.security.service;@Servicepublic class UserDetailServiceImpl implements UserDetailsService { @Autowired private BCryptPasswordEncoder passwordEncoder; /** * 當(dāng)我們執(zhí)行登錄操作時,底層會通過過濾器等對象,調(diào)用這個方法. * @param username 這個參數(shù)為頁面輸出的用戶名 * @return 一般是從數(shù)據(jù)庫基于用戶名查詢到的用戶信息 * @throws UsernameNotFoundException */ @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//1.基于用戶名從數(shù)據(jù)庫查詢用戶信息//User user=userMapper.selectUserByUsername(username);if(!'jack'.equals(username))//假設(shè)這是從數(shù)據(jù)庫查詢的信息 throw new UsernameNotFoundException('user not exists');//2.將用戶信息封裝到UserDetails對象中并返回//假設(shè)這個密碼是從數(shù)據(jù)庫查詢出來的String encodedPwd=passwordEncoder.encode('123456');//假設(shè)這個權(quán)限信息也是從數(shù)據(jù)庫查詢到的//假如分配權(quán)限的方式是角色,編寫字符串時用'ROLE_'做前綴List<GrantedAuthority> grantedAuthorities =AuthorityUtils.commaSeparatedStringToAuthorityList('ROLE_admin,ROLE_normal,sys:res:retrieve,sys:res:create');//這個user是SpringSecurity提供的UserDetails接口的實現(xiàn),用于封裝用戶信息//后續(xù)我們也可以基于需要自己構(gòu)建UserDetails接口的實現(xiàn)User user=new User(username,encodedPwd,grantedAuthorities);return user; }}

說明,這里的User對象會交給SpringSecurity框架,框架提取出密碼信息,然后與用戶輸入的密碼進行匹配校驗.

第三步:啟動服務(wù)進行登陸,訪問測試。

Spring Security 安全框架應(yīng)用原理解析

Spring Security 安全框架應(yīng)用原理解析

自定義登陸頁面

第一步:定義登陸頁面(直接在static目錄下創(chuàng)建即可),關(guān)鍵代碼如下:

<!DOCTYPE html><html lang='en'><head> <meta charset='utf-8'> <meta name='viewport' content='width=device-width, initial-scale=1, shrink-to-fit=no'> <meta name='description' content=''> <meta name='author' content=''> <title>Please sign in</title> <link rel='stylesheet' integrity='sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC' crossorigin='anonymous'></head><body><div class='container'> <form method='post' action='/login'><h2 class='form-signin-heading'>Please sign in</h2><p> <label for='username' class='sr-only'>Username</label> <input type='text' name='username' placeholder='Username' required autofocus></p><p> <label for='password' class='sr-only'>Password</label> <input type='password' name='password' placeholder='Password' required></p><input name='_csrf' type='hidden' value='cc1471a5-3246-43ff-bef7-31d714273899' /><button type='submit'>Sign in</button> </form></div></body></html>

注意:請求的url暫時為”/login”,請求方式必須為post方式,請求的參數(shù)暫時必須為username,password。這些規(guī)則默認在UsernamePasswordAuthenticationFilter中進行了定義。

第二步:修改安全配置類,讓其實現(xiàn)接口,并重寫相關(guān)config方法,進行登陸設(shè)計,代碼如下:

@Configurationpublic class SecutiryConfig extends WebSecurityConfigurerAdapter { @Bean public PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception {//super.configure(http);//關(guān)閉跨域攻擊,不關(guān)閉容易出錯http.csrf().disable();//自定義登陸表單http.formLogin()//設(shè)置登陸頁面.loginPage('/login.html')//設(shè)置登陸請求處理地址(對應(yīng)form表單中的action),登陸時會訪問UserDetailService對象.loginProcessingUrl('/login')//設(shè)置請求用戶名參數(shù)為username(默認就是username,可以自己修改,需要與表單同步).usernameParameter('username')//請求請求密碼參數(shù)為password(默認就是password,可以自己修改,需要與表單同步).passwordParameter('password')//設(shè)置登陸成功跳轉(zhuǎn)頁面(默認為/index.html).defaultSuccessUrl('/index.html')//登陸失敗訪問的頁面(默認為/login.html?error).failureUrl('/login.html?error');//認證設(shè)計http.authorizeRequests()//設(shè)置要放行的咨詢.antMatchers('/login.html').permitAll()//設(shè)置需要認證的請求(除了上面的要放行,其它都要進行認證).anyRequest().authenticated(); }}登陸成功和失敗處理器

現(xiàn)在的很多系統(tǒng)都采用的是前后端分離設(shè)計,我們登陸成功以后可能會跳轉(zhuǎn)到前端系統(tǒng)的某個地址,或者返回一個json數(shù)據(jù),我們可以自己定義登錄成功的處理操作,例如:

定義登陸成功處理器:

方案1:可以直接執(zhí)行重定向的處理器,例如

package com.cy.jt.auth.config.authentication;public class RedirectAuthenticationSuccessHandler implements AuthenticationSuccessHandler {//定義要跳轉(zhuǎn)的url private String redirectUrl; public RedirectAuthenticationSuccessHandler(String redirectUrl){this.redirectUrl=redirectUrl; } @Override public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { httpServletResponse.sendRedirect(redirectUrl); }}

方案2:可以直接返回JSON數(shù)據(jù)的處理器,例如:

package com.cy.jt.security.config.handler;/**處理登錄失敗 * 0)Default-默認 * 1)Authentication-認證 * 2)Failure-失敗 * 3)Handler-處理器 * */public class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandler { @Override public void onAuthenticationFailure( HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {//1.設(shè)置響應(yīng)數(shù)據(jù)的編碼httpServletResponse.setCharacterEncoding('utf-8');//2.告訴客戶端響應(yīng)數(shù)據(jù)的類型,以及客戶端以怎樣的編碼進行顯示httpServletResponse.setContentType('application/json;charset=utf-8');//3.獲取一個輸出流對象PrintWriter out=httpServletResponse.getWriter();//4.向客戶端輸出一個json格式字符串//4.1構(gòu)建一個map對象Map<String,Object> map=new HashMap<>();map.put('state','500');map.put('msg','username or password error');//4.2基于jackson中的ObjectMapper對象將一個對象轉(zhuǎn)換為json格式字符串String jsonStr= new ObjectMapper().writeValueAsString(map);out.println(jsonStr);out.flush(); }}

定義登陸失敗處理器:

方案1:登陸失敗重定向到頁面,例如

package com.cy.jt.auth.config.authentication;public class RedirectAuthenticationFailureSuccessHandler implements AuthenticationFailureHandler { private String redirectUrl; public RedirectAuthenticationFailureSuccessHandler(String redirectUrl){this.redirectUrl=redirectUrl; } @Override public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {httpServletResponse.sendRedirect(redirectUrl); }}

方案2:定義登陸失敗處理器,例如:

package com.cy.jt.security.config.handler;/**處理登錄失敗 * 0)Default-默認 * 1)Authentication-認證 * 2)Failure-失敗 * 3)Handler-處理器 * */public class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandler { @Override public void onAuthenticationFailure( HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {//1.設(shè)置響應(yīng)數(shù)據(jù)的編碼httpServletResponse.setCharacterEncoding('utf-8');//2.告訴客戶端響應(yīng)數(shù)據(jù)的類型,以及客戶端以怎樣的編碼進行顯示httpServletResponse.setContentType('application/json;charset=utf-8');//3.獲取一個輸出流對象PrintWriter out=httpServletResponse.getWriter();//4.向客戶端輸出一個json格式字符串//4.1構(gòu)建一個map對象Map<String,Object> map=new HashMap<>();map.put('state','500');map.put('msg','username or password error');//4.2基于jackson中的ObjectMapper對象將一個對象轉(zhuǎn)換為json格式字符串String jsonStr= new ObjectMapper().writeValueAsString(map);out.println(jsonStr);out.flush(); }}

修改配置類,設(shè)置登陸成功與失敗處理器。

@Configurationpublic class SecutiryConfig extends WebSecurityConfigurerAdapter { @Bean public PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception {//super.configure(http);//關(guān)閉跨域攻擊,不關(guān)閉容易出錯http.csrf().disable();//自定義登陸表單http.formLogin()//設(shè)置登陸頁面.loginPage('/login.html')//設(shè)置登陸請求處理地址(對應(yīng)form表單中的action),登陸時會訪問UserDetailService對象.loginProcessingUrl('/login')//設(shè)置請求用戶名參數(shù)為username(默認就是username,可以自己修改,需要與表單同步).usernameParameter('username')//請求請求密碼參數(shù)為password(默認就是password,可以自己修改,需要與表單同步).passwordParameter('password')//設(shè)置登陸成功跳轉(zhuǎn)頁面(默認為/index.html).successHandler(new RedirectAuthenticationSuccessHandler('你的url'))//登陸失敗訪問的頁面(默認為/login.html?error) .failureHandler(new RedirectAuthenticationFailureHandler('你的url'))//認證設(shè)計http.authorizeRequests()//設(shè)置要放行的咨詢.antMatchers('/login.html').permitAll()//設(shè)置需要認證的請求(除了上面的要放行,其它都要進行認證) .anyRequest().authenticated(); }}

第四步:啟動服務(wù)進行訪問測試(分別用正確和錯誤的賬號進行測試)。

放行靜態(tài)資源

在SecurityManager配置類中的configure(HttpSecurity http)方法中我們可以通過對anMatchers方法定義要放行靜態(tài)資源,例如:

.authorizeRequests() //設(shè)置請求的授權(quán).antMatchers( //配置下列路徑的授權(quán)'/index.html','/js/*','/css/*','/img/**','/bower_components/**','/login.html').permitAll() //設(shè)置上述所有路徑不需要登錄就能訪問(放行)

其中:

“*”用于匹配0個或多個字符 “**”用于匹配0個或多個目錄及字符登出設(shè)計及實現(xiàn)

在SecurityManager配置類中的configure(HttpSecurity http)方法中,添加登出配置,例如

http.logout() //開始設(shè)置登出信息.logoutUrl('/logout') //登出路徑.logoutSuccessUrl('/login.html?logout');//設(shè)置登出后顯示的頁面SpringSecurity授權(quán)邏輯實現(xiàn)修改授權(quán)配置類

在權(quán)限配置類上添加啟用全局方法訪問控制注解,例如:

package com.cy.auth.config;//這個配置類是配置Spring-Security的,//prePostEnabled= true表示啟動權(quán)限管理功能@EnableGlobalMethodSecurity(prePostEnabled = true)@Configurationpublic class SpringSecurityConfigurer extends WebSecurityConfigurerAdapter { ……}定義資源Controller

定義一個ResourceController類,作為資源訪問對象,例如

package com.cy.jt.auth.controller;@RestControllerpublic class ResourceController { @PreAuthorize('hasAuthority(’sys:res:create’)') @RequestMapping('/doCreate') public String doCreate(){return 'add resource'; } @PreAuthorize('hasAuthority(’sys:res:update’)') @RequestMapping('doUpdate') public String doUpdate(){return 'update resource'; } @PreAuthorize('hasAuthority(’sys:res:delete’)') @RequestMapping('/doDelete') public String doDelete(){return 'delete resource'; } @PreAuthorize('hasAuthority(’sys:res:retrieve’)') @RequestMapping('/doRetrieve') public String doRetrieve(){return 'retrieve resource'; }}

其中,@PreAuthorize注解描述方法時,用于告訴系統(tǒng)訪問此方法時需要進行權(quán)限檢測。需要具備指定權(quán)限才可以訪問。例如:

@PreAuthorize(“hasAuthority(’sys:res:delete”) 需要具備sys:res:delete權(quán)限 @PreAuthorize(“hasRole(‘a(chǎn)dmin’)”) 需要具備admin角色 啟動服務(wù)訪問測試

使用不同用戶進行登陸,然后執(zhí)行資源訪問,假如沒有權(quán)限,則會看到響應(yīng)狀態(tài)嗎403,如圖所示:

Spring Security 安全框架應(yīng)用原理解析

Spring認證和授權(quán)異常處理異常類型

對于SpringSecurity框架而言,在實現(xiàn)認證和授權(quán)業(yè)務(wù)時,可能出現(xiàn)如下兩大類型異常:1)AuthenticationException (用戶還沒有認證就去訪問某個需要認證才可訪問的方法時,可能出現(xiàn)的異常,這個異常通常對應(yīng)的狀態(tài)碼401)2)AccessDeniedException (用戶認證以后,在訪問一些沒有權(quán)限的資源時,可能會出現(xiàn)的異常,這個異常通常對應(yīng)的狀態(tài)嗎為403)

異常處理規(guī)范

SpringSecurity框架給了默認的異常處理方式,當(dāng)默認的異常處理方式不滿足我們實際業(yè)務(wù)需求時,此時我們就要自己定義異常處理邏輯,編寫邏輯時需要遵循如下規(guī)范:1)AuthenticationEntryPoint:統(tǒng)一處理 AuthenticationException 異常2)AccessDeniedHandler:統(tǒng)一處理 AccessDeniedException 異常.

自定義異常處理對象

處理沒有認證的訪問異常

package com.cy.jt.config;public class DefaultAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {//設(shè)置響應(yīng)數(shù)據(jù)的編碼response.setCharacterEncoding('utf-8');//告訴瀏覽器要響應(yīng)的內(nèi)容類型,以及編碼response.setContentType('application/json;charset=utf-8');Map<String,Object> map=new HashMap<>();map.put('state',401);map.put('message','請先登錄');PrintWriter out=response.getWriter();out.println(new ObjectMapper().writeValueAsString(map));out.flush();out.close(); }}

處理沒有權(quán)限時拋出的異常

package com.cy.jt.config;public class DefaultAccessDeniedExceptionHandler implements AccessDeniedHandler { @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException {//設(shè)置響應(yīng)數(shù)據(jù)的編碼response.setCharacterEncoding('utf-8');//告訴瀏覽器要響應(yīng)的內(nèi)容類型,以及編碼response.setContentType('application/json;charset=utf-8');Map<String,Object> map=new HashMap<>();map.put('state',403);map.put('message','沒有此資源的訪問權(quán)限');PrintWriter out=response.getWriter();out.println(new ObjectMapper().writeValueAsString(map));out.flush();out.close(); }}配置異常處理對象

在配置類SecurityConfig中添加自定義異常處理對象,代碼如下

http.exceptionHandling() .authenticationEntryPoint(new DefaultAuthenticationEntryPoint()) .accessDeniedHandler(new DefaultAccessDeniedExceptionHandler());

配置完成后,重啟服務(wù)進行訪問測試分析.

系統(tǒng)會話狀態(tài)分析與實踐 何為會話狀態(tài)

客戶端與服務(wù)端通訊過程中產(chǎn)生的狀態(tài)信息(類似會議記錄),稱之為會話狀態(tài).

會話狀態(tài)如何存儲

客戶端瀏覽器與服務(wù)端通訊時使用的是http協(xié)議,這個協(xié)議本身是無狀態(tài)協(xié)議,也就是說通過此協(xié)議,無法存儲會話狀態(tài),此時在服務(wù)端與客戶端就采用了一種Cookie與Session方式記錄會話狀態(tài).

有狀態(tài)的會話技術(shù)分析

Cookie 技術(shù)

Cookie是由服務(wù)端創(chuàng)建但在客戶端存儲會話狀態(tài)的一個對象,此對象分為兩種類型,一種為會話Cookie,一種為持久Cookie,瀏覽器在訪問具體的某個域名時會攜帶這個域的有效Cookie到服務(wù)端.

會話Cookie: 瀏覽器關(guān)閉Cookie生命周期結(jié)束(一般默認都是會話Cookie) 持久Cookie: 持久Cookie是在Cookie對象創(chuàng)建時指定了生命周期,例如一周時間,即便瀏覽器關(guān)閉,持久Cookie依舊有效. Session技術(shù)

Session技術(shù)由服務(wù)端創(chuàng)建,并在服務(wù)端存儲會話狀態(tài)的一個對象,當(dāng)Session對象創(chuàng)建時,還會創(chuàng)建一個會話Cookie對象,并且通過這個會話Cookie將SessionId寫到客戶端,客戶端下次訪問服務(wù)端會攜帶這個會話Cookie,并且通過JsessionId找到Session對象,進而獲取Session對象中存儲的數(shù)據(jù).Cookie默認的生命周期為30分鐘.

在SpringSecurity中獲取用戶的認證信息,就可以通過如下方式進行實現(xiàn):

Authentication authentication =SecurityContextHolder.getContext().getAuthentication();無狀態(tài)的會話技術(shù)分析

有狀態(tài)的會話實現(xiàn),在分布式架構(gòu)中可能會存在很多問題,例如瀏覽器默認不支持?jǐn)y帶其它域的Cookie信息進行資源訪問,同時服務(wù)端的Session默認不能共享,當(dāng)然我們有一種方式可以將session持久化到到一些數(shù)據(jù)庫,例如Redis,下次請求到其它服務(wù)器(例如tomcat)時,可以直接從redis中獲取登錄信息,但是假如并發(fā)比較大,數(shù)據(jù)庫的訪問壓力就會劇增,壓力太大有可能會導(dǎo)致系統(tǒng)宕機.所以現(xiàn)在還有一種方案就是將用戶的登錄狀態(tài)信息都存儲在客戶端,服務(wù)端不記錄任何狀態(tài),服務(wù)端只負責(zé)對客戶端傳遞過來的狀態(tài)信息進行解析,基于此方式進行用戶登錄狀態(tài)的判斷,這樣的會話過程稱之為無狀態(tài)會話.

總結(jié)(Summary)

重難點分析

SpringSecurity 產(chǎn)生背景? SpringSecurity 快速入門?(依賴,配置,登錄認證,密碼的加密-啟動生成,配置文件) SpringSecurity 認證邏輯分析及實踐?(認證方式-用戶名和密碼,登錄頁 面,SecurityConfig.UserServiceDetail,成功,失敗,放行) SpringSecurity 授權(quán)邏輯分析及實現(xiàn)?(為什么,授權(quán)步驟,用到的注解)

FAQ 分析

如何理解認證?(判定用戶身份的合法性) 如何校驗用戶身份的合法性?(用戶密碼,指紋,刷臉,刷身份證,…) 如何進行身份認證?(自己寫認證邏輯,借助框架去寫認證邏輯-尊重框架規(guī)則) 市場上的認證和授權(quán)框架有哪些?(SpringSecurity,Shiro) 為什么會選擇SpringSecurity?(功能強大,SpringBoot誕生后在配置方面做了大量的簡化) SpringSecurity中的加密方式你用的什么?(Bcrypt,底層基于隨機鹽方式對密碼進行hash不可逆加密,更加安全,缺陷是慢) SpringSecurity中你用過哪些API?(BcryptPasswordEncoder,UserDetailService,UserDetail,User, AuthenticationSuccessHandler,AuthenticationFailureHandler,…) 為什么要進行權(quán)限控制?(防止非法用戶破壞數(shù)據(jù)) SpringSecurity進行權(quán)限控制的步驟(@EnableGlobalMethodSecurity,@PreAuthorize) SpringSecurity在進行認證和授權(quán)時可能出現(xiàn)的異常? SpringSecurity在未認證和未授權(quán)的前提下訪問授權(quán)資源時,出現(xiàn)的異常如何處理? 作業(yè):用戶登錄成功以后,用戶信息默認存在哪里了? (Session) 作業(yè):用戶登錄成功以后,如何獲取我們登錄的用戶信息?(這個用戶的用戶名,這個用戶的權(quán)限)

Bug 分析

依賴下載不完整 響應(yīng)json數(shù)據(jù)時出現(xiàn)文件下載

到此這篇關(guān)于Spring Security 安全框架應(yīng)用的文章就介紹到這了,更多相關(guān)Spring Security框架內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
7777女厕盗摄久久久| 一区二区高清在线| 亚洲精品欧美二区三区中文字幕| 99麻豆久久久国产精品免费优播| 91精品国产欧美一区二区成人| 美女脱光内衣内裤视频久久网站 | 中文一区在线播放| 色综合中文字幕| 欧美成人一区二区三区片免费| 国产激情一区二区三区桃花岛亚洲| 欧美三级视频在线观看| 日本成人中文字幕| 欧美在线观看18| 免费日韩伦理电影| 欧美视频中文字幕| 国产最新精品免费| 91精品国产免费久久综合| 国产精品一区二区三区99| 欧美一区二区三区在线观看| 国产99久久久国产精品免费看| 日韩午夜电影av| 国产乱码字幕精品高清av| 欧美疯狂做受xxxx富婆| 国产a级毛片一区| 2014亚洲片线观看视频免费| 成人av资源站| 国产亚洲成aⅴ人片在线观看| 欧美国产高清| 中文字幕中文在线不卡住| 亚洲欧洲三级| 亚洲国产欧美一区二区三区丁香婷| 国产乱码精品| 日韩二区三区四区| 色成人在线视频| 久久99精品久久久久久动态图| 欧美日韩国产一二三| 国产麻豆午夜三级精品| 欧美成人a∨高清免费观看| 91免费看视频| 中文字幕一区二区三中文字幕| 国产精品日本| 卡一卡二国产精品| 欧美大尺度电影在线| 91亚洲精品久久久蜜桃网站| 国产精品护士白丝一区av| 一本色道久久综合| 婷婷丁香久久五月婷婷| 在线看一区二区| 国产乱人伦偷精品视频免下载| 精品理论电影在线观看| 欧美日韩一区自拍| 亚洲精品成人悠悠色影视| 久久天堂成人| 国产伦理精品不卡| 国产欧美综合色| 一区二区三区久久网| 久久99久久99小草精品免视看| 久久亚洲免费视频| 日韩视频在线播放| 日本欧美大码aⅴ在线播放| 日韩午夜av电影| 亚洲第一在线综合在线| 日本不卡123| 日韩精品一区二区在线观看| 亚洲天堂成人| 日韩精品亚洲专区| 日韩午夜在线观看视频| 伊大人香蕉综合8在线视| 午夜视频一区在线观看| 91精品国产麻豆国产自产在线 | 色综合久久天天综合网| 风间由美一区二区三区在线观看 | 麻豆久久一区二区| 精品久久99ma| 99亚洲视频| 国产一区二区三区av电影| 国产农村妇女精品| 久久三级福利| 99riav久久精品riav| 一级做a爱片久久| 69久久99精品久久久久婷婷| 欧美女人交a| 日本vs亚洲vs韩国一区三区| 久久久午夜电影| 亚洲一区二区网站| 国产99久久久国产精品潘金网站| 一区二区视频在线| 宅男噜噜噜66一区二区66| 亚洲国产一区二区三区在线播| 麻豆成人免费电影| 国产午夜精品美女毛片视频| 久久成人在线| 国产99久久久国产精品潘金网站| 亚洲欧美一区二区三区国产精品 | 中文字幕一区日韩精品欧美| 欧美色倩网站大全免费| 欧美日韩午夜| 精品中文字幕一区二区 | 国产剧情一区二区三区| 亚洲色图欧洲色图婷婷| 在线电影院国产精品| 在线精品观看| 国产高清不卡一区| 亚洲一二三四区不卡| 欧美精品一区视频| 91精品91久久久中77777| 欧美性天天影院| 国产成人一级电影| 午夜精品久久久久久久99樱桃 | 久久91精品久久久久久秒播| 国产精品久久久久毛片软件| 欧美私模裸体表演在线观看| 精品成人在线| 国产a视频精品免费观看| 亚洲午夜久久久| 久久蜜桃av一区二区天堂| 在线免费不卡视频| 日韩午夜激情| 成人一区二区三区| 免费高清在线一区| 亚洲男人都懂的| 欧美不卡123| 欧美最猛黑人xxxxx猛交| 亚洲欧洲一区二区在线观看| 懂色av一区二区夜夜嗨| 午夜伊人狠狠久久| 欧美国产精品劲爆| 日韩欧美在线观看一区二区三区| 久久久久欧美| 在线精品亚洲一区二区| av电影天堂一区二区在线| 久久99久久99小草精品免视看| 亚洲一区自拍偷拍| 欧美国产日韩一二三区| 欧美一区欧美二区| 在线观看日韩高清av| 国产亚洲精品v| 欧美日韩一区在线视频| 99免费精品在线观看| 国产在线不卡视频| 美腿丝袜亚洲三区| 亚洲国产cao| 亚洲色欲色欲www在线观看| 国产亚洲一区二区三区| 日韩一级完整毛片| 欧美日韩一区久久| 久久久久网站| 国产精品永久入口久久久| 亚洲国产一区二区三区a毛片| 欧美精品成人| 99re66热这里只有精品3直播 | 久热成人在线视频| 午夜精品久久久久久| 一区二区三区电影在线播| 国产精品区一区二区三区| 久久精品人人做人人爽97| 欧美成人免费网站| 欧美一区二区三区喷汁尤物| 欧美特级限制片免费在线观看| 色妞www精品视频| 久久国产精品久久w女人spa| 国产亚洲永久域名| 中文精品一区二区三区| 夜夜爽www精品| 一区二区av| 亚洲欧洲久久| 99国产精品久久久久老师| 激情婷婷亚洲| 精品不卡视频| 亚洲作爱视频| 亚洲理伦在线| 一区二区精品在线| 亚洲欧美精品| 麻豆精品视频| 色婷婷综合久久久久中文| 91精品办公室少妇高潮对白| 欧美自拍偷拍午夜视频| 欧美无砖砖区免费| 欧美日韩电影在线| 日韩一区二区在线看片| 日韩一区二区在线免费观看| 777午夜精品免费视频| 制服丝袜国产精品| 日韩欧美国产一区二区在线播放 | 国产精品hd| 国产精品二区三区四区| 亚洲午夜在线观看| 亚洲精选一区| 亚洲一区二区三区涩| 色噜噜狠狠色综合中国| 欧美无砖砖区免费| 678五月天丁香亚洲综合网| 欧美一区二区三区四区久久| 精品美女被调教视频大全网站| 久久久精品日韩欧美| 亚洲视频小说图片| 亚洲成人av一区| 麻豆久久久久久| 国产麻豆视频一区二区| zzijzzij亚洲日本少妇熟睡|