亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot整合Spring Security的詳細(xì)教程

 更新時間:2020年08月12日 09:15:49   作者:Robod丶  
這篇文章主要介紹了SpringBoot整合Spring Security的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

好好學(xué)習(xí),天天向上

本文已收錄至我的Github倉庫DayDayUP:github.com/RobodLee/DayDayUP,歡迎Star,更多文章請前往:目錄導(dǎo)航

前言

Spring Security是一個功能強大且高度可定制的身份驗證和訪問控制框架。提供了完善的認(rèn)證機制和方法級的授權(quán)功能。是一款非常優(yōu)秀的權(quán)限管理框架。它的核心是一組過濾器鏈,不同的功能經(jīng)由不同的過濾器。這篇文章就是想通過一個小案例將Spring Security整合到SpringBoot中去。要實現(xiàn)的功能就是在認(rèn)證服務(wù)器上登錄,然后獲取Token,再訪問資源服務(wù)器中的資源。

基本概念

單點登錄

什么叫做單點登錄呢。就是在一個多應(yīng)用系統(tǒng)中,只要在其中一個系統(tǒng)上登錄之后,不需要在其它系統(tǒng)上登錄也可以訪問其內(nèi)容。舉個例子,京東那么復(fù)雜的系統(tǒng)肯定不會是單體結(jié)構(gòu),必然是微服務(wù)架構(gòu),比如訂單功能是一個系統(tǒng),交易是一個系統(tǒng)......那么我在下訂單的時候登錄了,付錢難道還需要再登錄一次嗎,如果是這樣,用戶體驗也太差了吧。實現(xiàn)的流程就是我在下單的時候系統(tǒng)發(fā)現(xiàn)我沒登錄就讓我登錄,登錄完了之后系統(tǒng)返回給我一個Token,就類似于身份證的東西;然后我想去付錢的時候就把Token再傳到交易系統(tǒng)中,然后交易系統(tǒng)驗證一下Token就知道是誰了,就不需要再讓我登錄一次。

JWT

上面提到的Token就是JWT(JSON Web Token),是一種用于通信雙方之間傳遞安全信息的簡潔的、URL安全的表述性聲明規(guī)范。一個JWT實際上就是一個字符串,它由三部分組成,頭部、載荷與簽名。為了能夠直觀的看到JWT的結(jié)構(gòu),我畫了一張思維導(dǎo)圖:

最終生成的JWT令牌就是下面這樣,有三部分,用 . 分隔。

base64UrlEncode(JWT 頭)+"."+base64UrlEncode(載荷)+"."+HMACSHA256(base64UrlEncode(JWT 頭) + "." + base64UrlEncode(有效載荷),密鑰)

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

RSA

從上面的例子中可以看出,JWT在加密解密的時候都用到了同一個密鑰 “ robod666 ”,這將會帶來一個弊端,如果被黑客知道了密鑰的內(nèi)容,那么他就可以去偽造Token了。所以為了安全,我們可以使用非對稱加密算法RSA。

RSA的基本原理有兩點:

  • 私鑰加密,持有私鑰或公鑰才可以解密
  • 公鑰加密,持有私鑰才可解密

認(rèn)證服務(wù)器用戶登錄功能

前期準(zhǔn)備

介紹完了基本概念之后就可以開始整合了,受限于篇幅,只貼最核心的代碼,其它內(nèi)容請小伙伴們?nèi)ピ创a中找,地址在文末。 首先需要準(zhǔn)備好數(shù)據(jù)庫:

-- ----------------------------
-- Table structure for sys_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
 `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '編號',
 `ROLE_NAME` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '角色名稱',
 `ROLE_DESC` varchar(60) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '角色描述',
 PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of sys_role
-- ----------------------------
INSERT INTO `sys_role` VALUES (1, 'ROLE_USER', '基本角色');
INSERT INTO `sys_role` VALUES (2, 'ROLE_ADMIN', '超級管理員');
INSERT INTO `sys_role` VALUES (3, 'ROLE_PRODUCT', '管理產(chǎn)品');
INSERT INTO `sys_role` VALUES (4, 'ROLE_ORDER', '管理訂單');

-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `username` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用戶名稱',
 `password` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密碼',
 `status` int(1) NULL DEFAULT 1 COMMENT '1開啟0關(guān)閉',
 PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES (1, 'xiaoming', '$2a$10$CYX9OMv0yO8wR8rE19N2fOaXDJondci5uR68k2eQJm50q8ESsDMlC', 1);
INSERT INTO `sys_user` VALUES (2, 'xiaoma', '$2a$10$CYX9OMv0yO8wR8rE19N2fOaXDJondci5uR68k2eQJm50q8ESsDMlC', 1);

-- ----------------------------
-- Table structure for sys_user_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` (
 `UID` int(11) NOT NULL COMMENT '用戶編號',
 `RID` int(11) NOT NULL COMMENT '角色編號',
 PRIMARY KEY (`UID`, `RID`) USING BTREE,
 INDEX `FK_Reference_10`(`RID`) USING BTREE,
 CONSTRAINT `FK_Reference_10` FOREIGN KEY (`RID`) REFERENCES `sys_role` (`ID`) ON DELETE RESTRICT ON UPDATE RESTRICT,
 CONSTRAINT `FK_Reference_9` FOREIGN KEY (`UID`) REFERENCES `sys_user` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of sys_user_role
-- ----------------------------
INSERT INTO `sys_user_role` VALUES (1, 1);
INSERT INTO `sys_user_role` VALUES (2, 1);
INSERT INTO `sys_user_role` VALUES (1, 3);
INSERT INTO `sys_user_role` VALUES (2, 4);

SET FOREIGN_KEY_CHECKS = 1;

一共三張表,分別是用戶表,角色表,用戶-角色表。用戶是登錄用的,密碼其實就是加密過的字符串,內(nèi)容是“ 123 ”;角色是做權(quán)限控制時用的。

然后創(chuàng)建一個空的父工程SpringSecurityDemo,然后在父工程里面創(chuàng)建一個Module作為認(rèn)證服務(wù),名叫authentication_server。添加必要的依賴。(內(nèi)容較占篇幅,有需要的去源碼中獲取,源碼地址見文末)。

項目的配置文件內(nèi)容截取了核心的部分貼在下面:

…………
# 配置了公鑰和私鑰的位置
rsa:
 key:
 pubKeyPath: C:\Users\robod\Desktop\auth_key\id_key_rsa.pub
 priKeyPath: C:\Users\robod\Desktop\auth_key\id_key_rsa

最后的公私鑰的標(biāo)簽是自定義的,并不是Spring提供的標(biāo)簽,后面我們會在RSA的配置類中去加載這一部分內(nèi)容。

為了方便起見,我們還可以準(zhǔn)備幾個工具類(內(nèi)容較占篇幅,有需要的去源碼中獲取,源碼地址見文末):

  • JsonUtils:提供了json相關(guān)的一些操作;
  • JwtUtils:生成token以及校驗token相關(guān)方法;
  • RsaUtils:生成公鑰私鑰文件,以及從文件中讀取公鑰私鑰。

我們可以將載荷單獨封裝成一個對象:

@Data
public class Payload<T> {
 private String id;
 private T userInfo;
 private Date expiration;
}

現(xiàn)在再去寫一個測試類,調(diào)用RsaUtils中的相應(yīng)方法去生成公鑰和私鑰。那公鑰私鑰生成好了在使用的時候是怎么獲取的呢?為了解決這個問題,我們需要創(chuàng)建一個RSA的配置類,

@Data
@ConfigurationProperties("rsa.key") //指定配置文件的key
public class RsaKeyProperties {

 private String pubKeyPath;

 private String priKeyPath;

 private PublicKey publicKey;
 private PrivateKey privateKey;

 @PostConstruct
 public void createKey() throws Exception {
 this.publicKey = RsaUtils.getPublicKey(pubKeyPath);
 this.privateKey = RsaUtils.getPrivateKey(priKeyPath);
 }
}

首先我們使用了@ConfigurationProperties注解去指定公鑰私鑰路徑的key,然后在構(gòu)造方法中就可以去獲取到公鑰私鑰的內(nèi)容了。這樣在需要公鑰私鑰的時候就可以直接調(diào)用這個類了。但是不放入Spring容器中怎么調(diào)用這個類,所以在啟動類中添加一個注解:

@EnableConfigurationProperties(RsaKeyProperties.class)

這表示把RSA的配置類放入Spring容器中。

用戶登錄

在實現(xiàn)用戶登錄的功能之前,先說一下登錄的相關(guān)內(nèi)容。關(guān)于登錄流程我在網(wǎng)上看了篇文章感覺挺好的,貼出來給小伙伴們看看:

vue+springboot前后端分離實現(xiàn)單點登錄跨域問題解決方法

首先會進入UsernamePasswordAuthenticationFilter并且設(shè)置權(quán)限為null和是否授權(quán)為false,然后進入ProviderManager查找支持UsernamepasswordAuthenticationToken的provider并且調(diào)用provider.authenticate(authentication);再然后就是UserDetailsService接口的實現(xiàn)類(也就是自己真正具體的業(yè)務(wù)了),這時候都檢查過了后,就會回調(diào)UsernamePasswordAuthenticationFilter并且設(shè)置權(quán)限(具體業(yè)務(wù)所查出的權(quán)限)和設(shè)置授權(quán)為true(因為這時候確實所有關(guān)卡都檢查過了)。

在上面這段話中,提到了一個UsernamePasswordAuthenticationFilter,我們一開始進入的就是這個過濾器的attemptAuthentication()方法,但是這個方法是從form表單中獲取用戶名密碼,和我們的需求不符,所以我們需要重寫這個方法。然后經(jīng)過一系列的周轉(zhuǎn),進入到了UserDetailsService.loadUserByUsername()方法中,所以我們?yōu)榱藢崿F(xiàn)自己的業(yè)務(wù)邏輯,需要去實現(xiàn)這個方法。這個方法返回的是一個UserDetails接口對象,如果想返回自定義的對象,可以去實現(xiàn)這個接口。最終用戶驗證成功之后,調(diào)用的是UsernamePasswordAuthenticationFilter的父類AbstractAuthenticationProcessingFilter.successfulAuthentication()方法,我們也需要去重寫這個方法去實現(xiàn)我們自己的需求。

所以現(xiàn)在就來實現(xiàn)一下上面說的這些東西吧👇

@Data
public class SysUser implements UserDetails {

 private Integer id;
 private String username;
 private String password;
 private Integer status;
 private List<SysRole> roles = new ArrayList<>();	//SysRole封裝了角色信息,和登錄無關(guān),我放在后面講

	//這里還有幾個UserDetails中的方法,我就不貼代碼了

}

我們自定義了一個SysUser類去實現(xiàn)UserDetails接口,然后添加了幾個自定義的字段☝

public interface UserService extends UserDetailsService {
}
//-----------------------------------------------------------
@Service("userService")
public class UserServiceImpl implements UserService {
	…………
 @Override
 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
 SysUser sysUser = userMapper.findByUsername(username);
 return sysUser;
 }
}

在☝這段代碼中,我們先定義了一個接口UserService去繼承UserDetailsService,然后用UserServiceImpl實現(xiàn)了UserService,就相當(dāng)于UserServiceImpl實現(xiàn)了UserDetailsService,這樣我們就可以去實現(xiàn)loadUserByUsername()方法,內(nèi)容很簡單,就是用用戶名去數(shù)據(jù)庫中查出對應(yīng)的SysUser,然后具體的驗證流程就可以交給其它的過濾器去實現(xiàn)了,我們就不用管了。

前面提到了需要去重寫attemptAuthentication()和successfulAuthentication()方法,那就自定義一個過濾器去繼承UsernamePasswordAuthenticationFilter然后重寫這兩個方法吧👇

public class JwtLoginFilter extends UsernamePasswordAuthenticationFilter {

 private AuthenticationManager authenticationManager;
 private RsaKeyProperties rsaKeyProperties;

 public JwtLoginFilter(AuthenticationManager authenticationManager, RsaKeyProperties rsaKeyProperties) {
 this.authenticationManager = authenticationManager;
 this.rsaKeyProperties = rsaKeyProperties;
 }

 //這個方法是用來去嘗試驗證用戶的
 @Override
 public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
 try {
  SysUser user = JSONObject.parseObject(request.getInputStream(),SysUser.class);
  return authenticationManager.authenticate(
   new UsernamePasswordAuthenticationToken(
    user.getUsername(),
    user.getPassword())
  );
 } catch (Exception e) {
  try {
  response.setContentType("application/json;charset=utf-8");
  response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
  PrintWriter out = response.getWriter();
  Map<String, Object> map = new HashMap<>();
  map.put("code", HttpServletResponse.SC_UNAUTHORIZED);
  map.put("message", "賬號或密碼錯誤!");
  out.write(new ObjectMapper().writeValueAsString(map));
  out.flush();
  out.close();
  } catch (Exception e1) {
  e1.printStackTrace();
  }
  throw new RuntimeException(e);
 }
 }

 //成功之后執(zhí)行的方法
 @Override
 public void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
 SysUser sysUser = new SysUser();
 sysUser.setUsername(authResult.getName());
 sysUser.setRoles((List<SysRole>) authResult.getAuthorities());
 String token = JwtUtils.generateTokenExpireInMinutes(sysUser,rsaKeyProperties.getPrivateKey(),24*60);
 response.addHeader("Authorization", "RobodToken " + token);	//將Token信息返回給用戶
 try {
  //登錄成功時,返回json格式進行提示
  response.setContentType("application/json;charset=utf-8");
  response.setStatus(HttpServletResponse.SC_OK);
  PrintWriter out = response.getWriter();
  Map<String, Object> map = new HashMap<String, Object>(4);
  map.put("code", HttpServletResponse.SC_OK);
  map.put("message", "登陸成功!");
  out.write(new ObjectMapper().writeValueAsString(map));
  out.flush();
  out.close();
 } catch (Exception e1) {
  e1.printStackTrace();
 }
 }
}

代碼的邏輯還是很清晰的,我就不去講解了。

現(xiàn)在重點來了,Spring Security怎么知道我們要去調(diào)用自己的UserService和自定義的過濾器呢?所以我們需要配置一下,這也是使用Spring Security的一個核心——>配置類👇

@Configuration
@EnableWebSecurity //這個注解的意思是這個類是Spring Security的配置類
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	…………
 @Bean
 public BCryptPasswordEncoder passwordEncoder() {
 return new BCryptPasswordEncoder();
 }

 //認(rèn)證用戶的來源
 @Override
 protected void configure(AuthenticationManagerBuilder auth) throws Exception {
 auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
 }

 //配置SpringSecurity相關(guān)信息
 @Override
 public void configure(HttpSecurity http) throws Exception {
 http.csrf().disable() //關(guān)閉csrf
  .addFilter(new JwtLoginFilter(super.authenticationManager(),rsaKeyProperties))
  .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); //禁用session
 }

}

在配置類中,配置了認(rèn)證用戶的來源和添加了自定義的過濾器。這樣就可以實現(xiàn)登錄的功能了。

可以看到,現(xiàn)在已經(jīng)成功登錄了,但是這個/login是從哪兒來的呢,這個是Spring Security自己提供的,用戶名的鍵必須是”username“,密碼的鍵必須是 ”password“,提交方式必須是POST。

總結(jié)一下,實現(xiàn)登錄的功能需要做哪些操作:

  • 認(rèn)證用戶實現(xiàn)UserDetails接口
  • 用戶來源的Service實現(xiàn)UserDetailsService接口,實現(xiàn)loadUserByUsername()方法,從數(shù)據(jù)庫中獲取數(shù)據(jù)
  • 實現(xiàn)自己的過濾器繼承UsernamePasswordAuthenticationFilter,重寫attemptAuthentication()和successfulAuthentication()方法實現(xiàn)自己的邏輯
  • Spring Security的配置類繼承自WebSecurityConfigurerAdapter,重寫里面的兩個config()方法
  • 如果使用RSA非對稱加密,就準(zhǔn)備好RSA的配置類,然后在啟動類中加入注解將其加入IOC容器中

資源服務(wù)器權(quán)限校驗

在這一小節(jié),我們要實現(xiàn)去訪問資源服務(wù)器中的資源,并進行鑒權(quán)的操作。在父工程SpringSecirityDemo中再創(chuàng)建一個模塊recourse_server。因為我們現(xiàn)在并不需要從數(shù)據(jù)庫中獲取用戶信息。所以就不需要自己去定義Service和Mapper了。也不需要登錄的過濾器了。下面這張目錄結(jié)構(gòu)圖是資源服務(wù)工程所需要的所有東西。

SysRole上一節(jié)中用到了但是沒有詳細(xì)說明。這個類是用來封裝角色信息的,做鑒權(quán)的時候用的,實現(xiàn)了GrantedAuthority接口:

@Data
public class SysRole implements GrantedAuthority {

 private Integer id;
 private String roleName;
 private String roleDesc;

 /**
 * 如果授予的權(quán)限可以當(dāng)作一個String的話,就可以返回一個String
 * @return
 */
 @JsonIgnore
 @Override
 public String getAuthority() {
 return roleName;
 }

}

里面實現(xiàn)了getAuthority方法,直接返回roleName即可。roleName是角色名。

客戶端將Token傳到資源服務(wù)器中,服務(wù)器需要對Token進行校驗并取出其中的載荷信息。所以我們可以自定義一個過濾器繼承自BasicAuthenticationFilter,然后重寫doFilterInternal()方法,實現(xiàn)自己的邏輯。

public class JwtVerifyFilter extends BasicAuthenticationFilter {
	…………
 @Override
 protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
  throws IOException, ServletException {
 String header = request.getHeader("Authorization");
 //沒有登錄
 if (header == null || !header.startsWith("RobodToken ")) {
  chain.doFilter(request, response);
  response.setContentType("application/json;charset=utf-8");
  response.setStatus(HttpServletResponse.SC_FORBIDDEN);
  PrintWriter out = response.getWriter();
  Map<String, Object> map = new HashMap<String, Object>(4);
  map.put("code", HttpServletResponse.SC_FORBIDDEN);
  map.put("message", "請登錄!");
  out.write(new ObjectMapper().writeValueAsString(map));
  out.flush();
  out.close();
  return;
 }
 //登錄之后從token中獲取用戶信息
 String token = header.replace("RobodToken ","");
 SysUser sysUser = JwtUtils.getInfoFromToken(token, rsaKeyProperties.getPublicKey(), SysUser.class).getUserInfo();
 if (sysUser != null) {
  Authentication authResult = new UsernamePasswordAuthenticationToken
   (sysUser.getUsername(),null,sysUser.getAuthorities());
  SecurityContextHolder.getContext().setAuthentication(authResult);
  chain.doFilter(request, response);
 }
 }
}

在這段代碼中,先是從請求頭中獲取"Authorization"的值,如果值未null或者不是以我們規(guī)定的 “RobodToken ” 開頭就說明不是我們設(shè)置的Token,就是沒登錄,提示用戶登錄。有Token的話就調(diào)用JwtUtils.getInfoFromToken()去驗證并獲取載荷的內(nèi)容。驗證通過的話就在Authentication的構(gòu)造方法中把角色信息傳進去,然后交給其它過濾器去執(zhí)行即可。

私鑰應(yīng)該只保存在認(rèn)證服務(wù)器中,所以資源服務(wù)器中只要存公鑰就可以了。

…………
rsa:
 key:
 pubKeyPath: C:\Users\robod\Desktop\auth_key\id_key_rsa.pub
@Data
@ConfigurationProperties("rsa.key") //指定配置文件的key
public class RsaKeyProperties {

 private String pubKeyPath;

 private PublicKey publicKey;

 @PostConstruct
 public void createKey() throws Exception {
 this.publicKey = RsaUtils.getPublicKey(pubKeyPath);
 }
}

接下來就是Spring Security核心的配置文件了👇

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true) //開啟權(quán)限控制的注解支持,securedEnabled表示SpringSecurity內(nèi)部的權(quán)限控制注解開關(guān)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	…………
 //配置SpringSecurity相關(guān)信息
 @Override
 public void configure(HttpSecurity http) throws Exception {
 http.csrf().disable() //關(guān)閉csrf
  .authorizeRequests()
  .antMatchers("/**").hasAnyRole("USER") //角色信息
  .anyRequest() //其它資源
  .authenticated() //表示其它資源認(rèn)證通過后
  .and()
  .addFilter(new JwtVerifyFilter(super.authenticationManager(),rsaKeyProperties))
  .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); //禁用session
 }

}

這里面有個注解 @EnableGlobalMethodSecurity(securedEnabled = true),這個注解的意思是開啟權(quán)限控制的注解支持。然后添加了自定義的Token解析過濾器。最后在需要進行權(quán)限控制的方法上添加注解即可👇

@RestController
@RequestMapping("/product")
public class ProductController {

 @Secured("ROLE_PRODUCT")
 @RequestMapping("/findAll")
 public String findAll() {
 return "產(chǎn)品列表查詢成功";
 }

}

好了,這樣findAll方法就需要有"ROLE_PRODUCT"權(quán)限才能訪問。我們來測試一下:

登錄成功之后,響應(yīng)頭中有服務(wù)器返回的Token信息,把它復(fù)制下來,然后添加到我們請求的請求頭中。

可以看到,現(xiàn)在已經(jīng)成功訪問到資源了。再來換個沒有權(quán)限的用戶登錄測試一下:

請求被拒絕了,說明權(quán)限控制功能是沒有問題的??偨Y(jié)一下步驟:

  • 封裝權(quán)限信息的類實現(xiàn)GrantedAuthority接口,并實現(xiàn)里面的getAuthority()方法
  • 實現(xiàn)自己的Token校驗過濾器繼承自BasicAuthenticationFilter,并重寫doFilterInternal()方法,實現(xiàn)自己的業(yè)務(wù)邏輯
  • 編寫Spring Security的配置類繼承WebSecurityConfigurerAdapter,重寫configure()方法添加自定義的過濾器,并添加@EnableGlobalMethodSecurity(securedEnabled = true)注解開啟注解權(quán)限控制的功能
  • 如果使用RSA非對稱加密,就準(zhǔn)備好RSA的配置類,然后在啟動類中加入注解將其加入IOC容器中,注意這里不要只要配置公鑰即可

總結(jié)

SpringBoot 整合 Spring Security到這里就結(jié)束了。文章只是簡單的說了一下整合的流程,很多其它的東西都沒有說,比如各個過濾器都有什么作用等。還有,這里采用的認(rèn)證服務(wù)器和資源服務(wù)器分離的方式,要是集成在一起也是可以的。類似的問題還有很多,小伙伴們就自行研究吧。問了讓文章不會太臃腫,很多代碼都沒有貼出來,有需要的小伙伴點擊下面的鏈接就可以下載了。

點擊下載源碼

到此這篇關(guān)于SpringBoot整合Spring Security的文章就介紹到這了,更多相關(guān)SpringBoot整合Spring Security內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺談Spring中IOC的理解和認(rèn)知

    淺談Spring中IOC的理解和認(rèn)知

    這篇文章主要介紹了淺談Spring中IOC的理解和認(rèn)知,想了解Spring的同學(xué)不要錯過啊
    2021-04-04
  • ShardingSphere jdbc集成多數(shù)據(jù)源的實現(xiàn)步驟

    ShardingSphere jdbc集成多數(shù)據(jù)源的實現(xiàn)步驟

    本文主要介紹了ShardingSphere jdbc集成多數(shù)據(jù)源的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • SpringBoot+layuimini實現(xiàn)左側(cè)菜單動態(tài)展示的示例代碼

    SpringBoot+layuimini實現(xiàn)左側(cè)菜單動態(tài)展示的示例代碼

    Layuimini是Layui的升級版,它是專業(yè)做后臺頁面的框架,而且是適合PC端和移動端,以下地址可以在PC端顯示,也可以在手機上顯示,只不過會做自適應(yīng),本文將給大家介紹了SpringBoot+layuimini實現(xiàn)左側(cè)菜單動態(tài)展示的方法,需要的朋友可以參考下
    2024-04-04
  • 流讀取導(dǎo)致StringBuilder.toString()亂碼的問題及解決

    流讀取導(dǎo)致StringBuilder.toString()亂碼的問題及解決

    這篇文章主要介紹了流讀取導(dǎo)致StringBuilder.toString()亂碼的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Java設(shè)計模式之模板方法模式Template Method Pattern詳解

    Java設(shè)計模式之模板方法模式Template Method Pattern詳解

    在我們實際開發(fā)中,如果一個方法極其復(fù)雜時,如果我們將所有的邏輯寫在一個方法中,那維護起來就很困難,要替換某些步驟時都要重新寫,這樣代碼的擴展性就很差,當(dāng)遇到這種情況就要考慮今天的主角——模板方法模式
    2022-11-11
  • shiro無狀態(tài)web集成的示例代碼

    shiro無狀態(tài)web集成的示例代碼

    本篇文章主要介紹了shiro無狀態(tài)web集成的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • Java平臺調(diào)試體系原理分析和實踐整理 遠(yuǎn)程Debug

    Java平臺調(diào)試體系原理分析和實踐整理 遠(yuǎn)程Debug

    這篇文章主要介紹了Java平臺調(diào)試體系原理分析和實踐整理 遠(yuǎn)程Debug,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Spring?Cloud集成Nacos?Config動態(tài)刷新源碼剖析

    Spring?Cloud集成Nacos?Config動態(tài)刷新源碼剖析

    這篇文章主要為大家介紹了Spring?Cloud集成Nacos?Config動態(tài)刷新源碼剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • Java異步編程工具Twitter?Future詳解

    Java異步編程工具Twitter?Future詳解

    這篇文章主要介紹了Java異步編程工具Twitter?Future詳解,包括基本用法示例代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • spring入門教程之bean的繼承與自動裝配詳解

    spring入門教程之bean的繼承與自動裝配詳解

    眾所周知Spring里面的bean就類似是定義的一個組件,而這個組件的作用就是實現(xiàn)某個功能的,下面這篇文章主要給大家介紹了關(guān)于spring入門教程之bean繼承與自動裝配的相關(guān)資料,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11

最新評論