網(wǎng)站首頁 編程語言 正文
Security前后端分離自定義登錄
思路:
通過自定義接口去處理前端的登錄請求,其主要問題就是如何實現(xiàn)登錄的認(rèn)證!我們需要手動調(diào)用security的認(rèn)證,并且在security配置類中需要定義一些東西
解決:
security配置類(我這里只是測試,根據(jù)個人使用更改即可):
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
// 查詢用戶信息
provider.setUserDetailsService(userDetailsService());
// 設(shè)置密碼加密算法
provider.setPasswordEncoder(passwordEncoder());
auth.authenticationProvider(provider);
}
@Bean
@Override
//構(gòu)建用戶(可以從數(shù)據(jù)庫查找、內(nèi)存模擬,這里為了方便就使用內(nèi)存構(gòu)建)
protected UserDetailsService userDetailsService() {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("zhangsan").password("123456").authorities("p1").build());
manager.createUser(User.withUsername("lisi").password("123456").authorities("p2").build());
return manager;
}
@Bean
//生成密碼編碼類,像MD5,這里使用的這個是直接比較String
public PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
@Override
//security配置,核心
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
//訪問/test/1,需要p1權(quán)限
.antMatchers("/test/1").hasAnyAuthority("p1")
//訪問/test/2,需要p2權(quán)限
.antMatchers("/test/2").hasAnyAuthority("p2")
//test下的請求都必須認(rèn)證(登錄)后才能訪問
.antMatchers("/test/**").authenticated()
//無條件放行test/** 以外的請求
.anyRequest().permitAll();
}
@Override
@Bean
public AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
}
測試接口:
@RestController
public class TestController {
@Resource
AuthenticationManager authenticationManager;
@GetMapping("/mylogin")
public String test(String username, String password){
//生成驗證令牌
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username,password);
//獲取驗證完成的認(rèn)證信息
Authentication authenticate = authenticationManager.authenticate(token);
//保存到security上下文中
SecurityContextHolder.getContext().setAuthentication(authenticate);
return "登錄成功";
}
@GetMapping("/test/1")
public String test1(){
return "有p1權(quán)限,認(rèn)證后才能看到這條消息";
}
@GetMapping("/test/2")
public String test2(){
return "有p2權(quán)限,認(rèn)證后才能看到這條消息";
}
}
詳解:
1.配置類中此方法
為什么需要使用DaoAuthenticationProvider,使用為我們使用用戶名密碼是使用UsernamePasswordAuthenticationToken生成的驗證令牌(登錄接口中也是這樣寫的),而UsernamePasswordAuthenticationToken類型的驗證令牌最終會匹配到DaoAuthenticationProvider來進(jìn)行驗證(因為只有他能驗證這種類型的)。
我們需要給這個驗證提供者(DaoAuthenticationProvider)提供用戶信息和密碼使用什么加密算法。
提供用戶信息即圖中:setUserDetailsService(),其中的userDetailsService()方法是你在配置類中定義的,里面你可以自定定義邏輯,比如最常用的數(shù)據(jù)庫查詢用戶信息
加密算法即圖中:setPasswordEncoder(),其中的passwordEncoder()方法也是在配置類中定義的,稍后會講解那一塊
2.配置類的userDetailsService()方法
這里是在內(nèi)存中創(chuàng)建的數(shù)據(jù),要查數(shù)據(jù)庫怎么玩??(見名知意它是個service,service掉dao就能拿到用戶信息了)
@Override
@Bean
protected UserDetailsService userDetailsService() {
return new UserDetailsServiceImpl();
}
你需要寫一個類實現(xiàn)UserDetailsService,實現(xiàn)其方法loadUserByUsername(String username)即可,在這個方法里面你就可以調(diào)用dao去查這個用戶,并將其返回(返回類型是userdetails),所以用戶實體類必須繼承User類:如下介紹
是Security中的User類
import org.springframework.security.core.userdetails.User;
這個security中的User,該User實現(xiàn)了UserDetails,所以我們繼承即可。繼承之后我們只需要創(chuàng)建兩個
構(gòu)造函數(shù)即可,它有錯誤提示,點一下就幫我們創(chuàng)建好了:
public class MyUser extends User {
private String userName;
private String password;
public MyUser(String username, String password, Collection extends GrantedAuthority> authorities) {
super(username, password, authorities);
}
public MyUser(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection extends GrantedAuthority> authorities) {
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
}
}
3. 密碼加密方式
其作用是選擇一個密碼加密方式,就是在做密碼比對的時候,用什么加密方式去加密前端傳來的密碼,然后再和數(shù)據(jù)庫中的密碼比較!
4.注入AuthenticionManager
就是注入一個認(rèn)證管理器,非要說些什么的話,就說說它是個什么吧。
AuthenticionManager是一個接口,看它的意思就知道它是管理認(rèn)證的,該接口中也只有一個認(rèn)證方法:
看看它的實現(xiàn)類
其實現(xiàn)類ProviderManager(它是做認(rèn)證的,delegator結(jié)尾的是授權(quán)的。我也不敢確定說對沒有。。)就是我們用到的,它會幫我們找到能夠驗證的認(rèn)證提供類(即DaoAuthenticionProvider)
5.我的登錄接口為啥用的get請求方式
不知道你們注意到我的登錄接口是get請求沒有,是這樣的:
因為我并沒有寫前端,我之前使用的post方式,我圖方便就在postman上測的,能夠登錄成功也確實認(rèn)證成功,但是,并不能訪問需要身份認(rèn)證后才能訪問的請求,我明明已經(jīng)認(rèn)證成功了呀?
是因為,認(rèn)證成功之后,你的認(rèn)證信息會被放到session中:
如圖,這是security初始化內(nèi)部實例時(springboot啟動的時候),使用的就是httpsession,你要問在哪用到了這個repo:
我們只需要在接口中,將認(rèn)證信息保存到security上下文即可,后續(xù)就交給security處理:
所以,你必須在同一個瀏覽器中先登錄認(rèn)證才能有這個session,也就才能訪問得到你有權(quán)訪問的請求(當(dāng)然你也可以在postman中加上這個session,不過就麻煩很多,我使用get效果一樣的)
最后這里有一篇不錯的關(guān)于security前后端分離登錄的文章:https://blog.csdn.net/ycf921244819/article/details/108538506
這里是我分析的security認(rèn)證過程源碼(有點亂,但最后兩張圖比較清晰),有興趣的可以來看看:
https://blog.csdn.net/qq_42682745/article/details/120713818
原文鏈接:https://blog.csdn.net/qq_42682745/article/details/121326021
相關(guān)推薦
- 2023-01-09 Spark處理trick總結(jié)分析_相關(guān)技巧
- 2023-01-29 React基于路由的代碼分割技術(shù)詳解_React
- 2022-12-11 internal修飾符探索kotlin可見性控制詳解_Android
- 2022-11-21 Redis不同數(shù)據(jù)類型的命令語句詳解_Redis
- 2022-05-17 qt 解決Error while building/deploying project Hmi (k
- 2023-12-12 設(shè)置線程名稱(兩種方法)
- 2022-09-12 C++實例分析組合數(shù)的計算與排列組合的產(chǎn)生_C 語言
- 2022-05-23 python列表排序用?sort()和sorted()的區(qū)別_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支