springboot整合springsecurity與mybatis-plus的簡單實(shí)現(xiàn)
1、概述
Spring Security是一個(gè)功能強(qiáng)大且高度可定制的身份驗(yàn)證和訪問控制框架。
它是用于保護(hù)基于Spring的應(yīng)用程序的實(shí)際標(biāo)準(zhǔn)。
Spring Security是一個(gè)框架,致力于為Java應(yīng)用程序提供身份驗(yàn)證和授權(quán)。
與所有Spring項(xiàng)目一樣,Spring Security的真正強(qiáng)大之處在于可以輕松擴(kuò)展以滿足自定義要求
springboot對(duì)于springSecurity提供了自動(dòng)化配置方案,可以使用更少的配置來使用springsecurity
而在項(xiàng)目開發(fā)中,主要用于對(duì)用戶的認(rèn)證和授權(quán)
官網(wǎng):https://spring.io/projects/spring-security
2、數(shù)據(jù)庫使用Mysql,使用mybatis-plus框架
3、大致結(jié)構(gòu)圖如下:

控制器用HelloController就行,因?yàn)槭褂胢ybatis-plus代碼生成的有一些沒用的配置
4、使用依賴如下:
spring-boot用的2.1.18 RELEASE

5、application.properties配置文件如下:
# 數(shù)據(jù)庫驅(qū)動(dòng): spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # 數(shù)據(jù)庫連接地址 spring.datasource.url=jdbc:mysql:///rog?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai # 數(shù)據(jù)庫用戶名&密碼: spring.datasource.username=root spring.datasource.password=root #日志輸出,使用默認(rèn)的控制臺(tái)輸出 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl #mybatis plus 設(shè)置 mybatis-plus.mapper-locations=classpath*:com/xxx/mapper/xml/*Mapper.xml #配置別名掃描 mybatis-plus.type-aliases-package=com.xxx.entity
6、mysql數(shù)據(jù)庫
這里使用了3張表,分別是user、role、user_role



7、entity-實(shí)體類大致如下:

注意需要對(duì)應(yīng)數(shù)據(jù)庫的id自動(dòng)遞增
8、mapper包

因?yàn)槭褂玫膍abits-plus代碼生成所以對(duì)應(yīng)的mapper,所以生成好是繼承了BaseMapper,如果手動(dòng)寫的話,就需要繼承BaseMapper

查詢數(shù)據(jù)庫當(dāng)前請(qǐng)求登錄的用戶,獲取他所擁有的所有權(quán)限
9、service
@Service()
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements IUsersService, UserDetailsService {
@Autowired
private UsersMapper usersMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
QueryWrapper<Users> wrapper = new QueryWrapper<>();
wrapper.eq("user_name",username);
//根據(jù)頁面?zhèn)鞯挠脩裘檎覕?shù)據(jù)庫判斷是否存在該用戶
Users users = usersMapper.selectOne(wrapper);
if (users==null){
throw new UsernameNotFoundException("用戶不存在");
}
List<Role> roles = usersMapper.findRoles(users.getId());
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
//遍歷當(dāng)前用戶的角色集合組裝權(quán)限
for (Role role : roles) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
return new User(username,users.getPassword(),authorities);//如果用戶沒有角色會(huì)NullPointerException
}
}
需要實(shí)現(xiàn) UserDetailsService接口重寫 loadUserByUsername方法,做了一個(gè)簡單邏輯
10、測試是否連接上了數(shù)據(jù)庫


新增一個(gè)用戶,數(shù)據(jù)新增成功返回row>0,表示已經(jīng)連接數(shù)據(jù)庫成功
11、controller層寫一個(gè)簡單的控制器

12、config包下配置一下權(quán)限認(rèn)證框架配置
@Configuration
@MapperScan("com.xxx.mapper")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Bean
PasswordEncoder passwordEncoder() {
//使用明文密碼:為了簡單方便測試
return NoOpPasswordEncoder.getInstance();
//暗文密碼:會(huì)用salt加密
// return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//設(shè)置注入的自定義認(rèn)證實(shí)現(xiàn)類userService,必須實(shí)現(xiàn)了UserDetailsService接口
auth.userDetailsService(userDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
//.antMatchers需要寫在 .anyRequest()之前
/* anyRequest 已經(jīng)包含了其他請(qǐng)求了,在它之后如果還配置其他請(qǐng)求也沒有任何意義。
anyRequest 應(yīng)該放在最后,表示除了前面攔截規(guī)則之外,剩下的請(qǐng)求要如何處理。具體可以稍微查看一下源碼,
在攔截規(guī)則的配置類 AbstractRequestMatcherRegistry 中*/
.antMatchers("/admin/**").hasRole("admin")//以/admin作為前綴的請(qǐng)求必須具有admin權(quán)限才能訪問(當(dāng)前也必須認(rèn)證通過)
.antMatchers("/user/**").hasRole("user")//以/user作為前綴的請(qǐng)求必須具有user權(quán)限才能訪問(當(dāng)前也必須認(rèn)證通過)
.anyRequest().authenticated()//任何請(qǐng)求都認(rèn)證過放行
.and()//方法表示結(jié)束當(dāng)前標(biāo)簽,上下文回到HttpSecurity,開啟新一輪的配置。
.formLogin()//使用表單認(rèn)證
.loginProcessingUrl("/doLogin")//指定登錄頁面提交數(shù)據(jù)的接口
.successHandler((req, resp, authentication) -> {
Object principal = authentication.getPrincipal();//獲取認(rèn)證成功的用戶對(duì)象
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
//使用Jackson將對(duì)象轉(zhuǎn)換為JSON字符串
out.write(new ObjectMapper().writeValueAsString(principal));//將登錄成功的對(duì)象基于JSON響應(yīng)
out.flush();
out.close();
})
.failureHandler((req, resp, e) -> {//根據(jù)異常信息判斷哪一操作出現(xiàn)錯(cuò)誤
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
Map<String, Object> map = new HashMap<String, Object>();
map.put("status", 400);
if (e instanceof LockedException) {
map.put("msg", "賬戶被鎖定,請(qǐng)聯(lián)系管理員!");
} else if (e instanceof CredentialsExpiredException) {
map.put("msg", "密碼過期,請(qǐng)聯(lián)系管理員!");
} else if (e instanceof AccountExpiredException) {
map.put("msg", "賬戶過期,請(qǐng)聯(lián)系管理員!");
} else if (e instanceof DisabledException) {
map.put("msg", "賬戶被禁用,請(qǐng)聯(lián)系管理員!");
} else if (e instanceof BadCredentialsException) {
map.put("msg", "用戶名或者密碼輸入錯(cuò)誤,請(qǐng)重新輸入!");
}
out.write(new ObjectMapper().writeValueAsString(map));
out.flush();
out.close();
})
.permitAll()//放行自定義登錄頁面請(qǐng)求
.and()
.logout()//默認(rèn)注銷接口/logout
.logoutUrl("/logout")//默認(rèn)注銷的URL
//基于前后端分離開發(fā),前端發(fā)起/logout請(qǐng)求,后端自定義注銷成功處理邏輯:返回json提示成功
.logoutSuccessHandler((req, resp, authentication) -> {
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
out.write("注銷成功");
out.flush();
out.close();
})
.permitAll()
.and()
.csrf().disable()//關(guān)閉csrf攻擊攔截
//配置未認(rèn)證提示,給未認(rèn)證(登錄成功)訪問其他請(qǐng)求時(shí),給前端響應(yīng)json提示
.exceptionHandling()
.authenticationEntryPoint((req, resp, authException) -> {
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
out.write("尚未登錄,請(qǐng)先登錄");
out.flush();
out.close();
}
);
}
}
因?yàn)槭褂胮ostman測試所有就沒有寫自定義頁面,如果自定義登錄界面需要配置一個(gè)靜態(tài)資源放行

13、postman測試

登錄需要使用post請(qǐng)求,和表單提交方式
右邊響應(yīng)格式,如果你的實(shí)體沒有實(shí)現(xiàn)UserDetails接口,返回的json格式便是固定的
屬性對(duì)應(yīng)分別是accountNonExpired、accountNonLocked、credentialsNonExpired、enabled 這四個(gè)屬性分別用來描述用戶的狀態(tài),表示賬戶是否沒有過期、賬戶是否沒有被鎖定、密碼是否沒有過期、以及賬戶是否可用。
不需要任何授權(quán)即可訪問:

需要用戶權(quán)限才能訪問:

需要管理員權(quán)限才能訪問(當(dāng)前登錄用戶沒有管理員權(quán)限所以他無法訪問當(dāng)前頁面):

注銷當(dāng)前登錄用戶,會(huì)默認(rèn)清除Cookies以及認(rèn)證信息和使session失效,當(dāng)然也可以在配置類中顯示配置一下


再次訪問頁面,就會(huì)提示先登錄在訪問

以上就是Spring Security 簡單整合mybatis-plus大概的過程,個(gè)人覺得還算是比較詳細(xì)哈哈。。。
到此這篇關(guān)于springboot整合springsecurity與mybatis-plus的簡單實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)springboot整合spring security內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Springboot安全框架整合SpringSecurity實(shí)現(xiàn)方式
- springboot整合security和vue的實(shí)踐
- SpringBoot如何整合Springsecurity實(shí)現(xiàn)數(shù)據(jù)庫登錄及權(quán)限控制
- SpringBoot整合SpringSecurityOauth2實(shí)現(xiàn)鑒權(quán)動(dòng)態(tài)權(quán)限問題
- Springboot詳解整合SpringSecurity實(shí)現(xiàn)全過程
- SpringBoot整合SpringSecurity實(shí)現(xiàn)JWT認(rèn)證的項(xiàng)目實(shí)踐
- SpringBoot整合Security權(quán)限控制登錄首頁
- SpringBoot整合Spring?Security過濾器鏈加載執(zhí)行流程源碼分析(最新推薦)
- SpringBoot整合SpringSecurity和JWT和Redis實(shí)現(xiàn)統(tǒng)一鑒權(quán)認(rèn)證
- SpringBoot整合SpringSecurity認(rèn)證與授權(quán)
- SpringBoot整合Spring Security構(gòu)建安全的Web應(yīng)用
相關(guān)文章
JAVA正則表達(dá)式及字符串的替換與分解相關(guān)知識(shí)總結(jié)
今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識(shí)總結(jié),文章圍繞著JAVA正則表達(dá)式及字符串的替換與分解展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
使用feign傳遞參數(shù)類型為MultipartFile的問題
這篇文章主要介紹了使用feign傳遞參數(shù)類型為MultipartFile的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
淺談java7增強(qiáng)的try語句關(guān)閉資源
下面小編就為大家?guī)硪黄獪\談java7增強(qiáng)的try語句關(guān)閉資源。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06
rabbitmq使用springboot實(shí)現(xiàn)direct模式(最新推薦)
這篇文章主要介紹了rabbitmq使用springboot實(shí)現(xiàn)direct模式,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07
MybatisPlus字段自動(dòng)填充失效,填充值為null的解決方案
這篇文章主要介紹了MybatisPlus字段自動(dòng)填充失效,填充值為null的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
String轉(zhuǎn)BigDecimal,BigDecimal常用操作,以及避免踩坑記錄
這篇文章主要介紹了String轉(zhuǎn)BigDecimal,BigDecimal常用操作,以及避免踩坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07

