SpringSecurity微服務(wù)實(shí)戰(zhàn)之公共模塊詳解
前言
在項(xiàng)目中安全框架是必不可少的,在微服務(wù)架構(gòu)中更是尤為重要,我們項(xiàng)目中將安全模塊單獨(dú)抽離了一個(gè)公共模塊出來,因?yàn)樵谖业捻?xiàng)目架構(gòu)中 需要用到的SpringSecurity 至少有三個(gè)地方 boss服務(wù) admin服務(wù) user服務(wù)(saas)模式的一個(gè)微服務(wù)架構(gòu)
模塊結(jié)構(gòu)
主要分為 base服務(wù)(提供數(shù)據(jù),可以部署多份進(jìn)行負(fù)載均衡) boss模塊 admin模塊 gateway模塊 以及公共模塊其中就包含我們今天的主角 安全模塊。

我們在TokenLoginFilter中繼承 AbstractAuthenticationProcessingFilter抽象類 重寫 attemptAuthentication方法 在里面分別指定驗(yàn)證器
@Override
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {
if (!httpServletRequest.getMethod().equals("POST")) {
throw new AuthenticationServiceException(
"Authentication method not supported: " + httpServletRequest.getMethod());
}
User user = new ObjectMapper().readValue( httpServletRequest.getInputStream(), User.class);
//處理驗(yàn)證碼
AbstractAuthenticationToken authRequest = null;
switch(user.getType()) {
//租戶登錄
case "1":
authRequest = new TenantAuthenticationToken(user.getUsername(), user.getPassword());
break;
//平臺(tái)登錄
case "2":
authRequest = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
break;
}
setDetails(httpServletRequest, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
其中TenantDetailsAuthenticationProvider租戶驗(yàn)證器(admin) 和UsernamePasswordAuthenticationProvider 平臺(tái)驗(yàn)證器(boss)

這里當(dāng)然還可以再加其他的驗(yàn)證器,比如后面如果還有app的話就可以在配置一個(gè)專門來做app端權(quán)限驗(yàn)證的驗(yàn)證器。
下面我們看看令牌的續(xù)期是怎么實(shí)現(xiàn)的: 令牌是由jwt生成 和 redis 配合使用,每一次親求進(jìn)來檢查token是否合法的同時(shí)校驗(yàn)一下token的剩余時(shí)間是否大于一個(gè)閾值,如果小于閾值我們進(jìn)行reids 中的令牌刷新時(shí)間讓用戶無感知續(xù)約。
/**
* 驗(yàn)證令牌有效期,相差不足20分鐘,自動(dòng)刷新緩存
* @param loginUser
* @return 令牌
*/
public void verifyToken(OnlineUserInfo loginUser,Integer type)
{
long expireTime = loginUser.getExpireTime();
long currentTime = System.currentTimeMillis();
long chazhu= expireTime - currentTime;
if (chazhu <= MILLIS_MINUTE_TEN)
{
refreshToken(loginUser,type);
}
}
在訪問過濾器中進(jìn)行校驗(yàn)就可以了,這樣就可以做到用戶無感知令牌續(xù)約。
安全驗(yàn)證模塊目前是再每個(gè)服務(wù)上面引入使用,后面會(huì)考慮在網(wǎng)關(guān)層做鑒權(quán)處理。
最后貼一下 WebSecurityConfigBugVip 這個(gè)配置類
@Configuration
@EnableWebSecurity
public class WebSecurityConfigBugVip extends WebSecurityConfigurerAdapter {
private TokenManager tokenManager;
@Autowired
private TenantDetailsAuthenticationProvider userDetailsAuthenticationProvider;
@Autowired
private UsernamePasswordAuthenticationProvider usernamePasswordAuthenticationProvider;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
/**
* 裝配自定義的Provider
* @param auth
*/
@Override
public void configure(AuthenticationManagerBuilder auth){
auth.authenticationProvider(userDetailsAuthenticationProvider);//將我們自定義的認(rèn)證器配置進(jìn)來
auth.authenticationProvider(usernamePasswordAuthenticationProvider);//默認(rèn)的認(rèn)證器
}
@Autowired
public WebSecurityConfigBugVip(TokenManager tokenManager, RedisTemplate redisTemplate) {
this.tokenManager = tokenManager;
this.redisTemplate = redisTemplate;
}
/**
* 配置設(shè)置
*
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling()
.authenticationEntryPoint(new UnauthorizedEntryPoint())
.and().csrf().disable()
.addFilterAt(tokenLoginFilter(), UsernamePasswordAuthenticationFilter.class)
.authorizeRequests()//配置需要放行的請求
.antMatchers("/swagger-ui.html/**","/v2/**","/webjars/**","/swagger-resources/**","/boss/verifi/getCode","/boss/verifi/checkVrrifyCode","/boss/sysuser/write","/boss/sysuser/read").permitAll()
.anyRequest().authenticated()
.and().logout().logoutUrl("/boss/acl/logout")
.and().logout().logoutUrl("/admin/acl/logout")
.addLogoutHandler(new TokenLogoutHandler(tokenManager, redisTemplate)).and()
.addFilter(new TokenAuthenticationFilter(authenticationManager(), tokenManager, redisTemplate)).httpBasic();//設(shè)置訪問過濾器
}
/**
*token過濾器
*/
@Bean
public TokenLoginFilter tokenLoginFilter() {
TokenLoginFilter filter = new TokenLoginFilter();
filter.setAuthenticationManager(authenticationManager);
return filter;
}
/**
* 處理注入 AuthenticationManager失敗問題
* @return
* @throws Exception
*/
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}以上就是SpringSecurity微服務(wù)實(shí)戰(zhàn)之公共模塊詳解的詳細(xì)內(nèi)容,更多關(guān)于SpringSecurity微服務(wù)公共模塊的資料請關(guān)注腳本之家其它相關(guān)文章!
- Spring?Security?登錄時(shí)添加圖形驗(yàn)證碼實(shí)現(xiàn)實(shí)例
- SpringBoot?Security權(quán)限控制自定義failureHandler實(shí)例
- SpringBoot整合Security權(quán)限控制登錄首頁
- SpringBoot?整合Security權(quán)限控制的初步配置
- Spring?Security自定義登錄頁面認(rèn)證過程常用配置
- Spring?Security密碼解析器PasswordEncoder自定義登錄邏輯
- Spring Security整合KeyCloak保護(hù)Rest API實(shí)現(xiàn)詳解
相關(guān)文章
SpringBoot集成cache緩存的實(shí)現(xiàn)
日常開發(fā)中,緩存是解決數(shù)據(jù)庫壓力的一種方案,本文記錄springboot中使用cache緩存。需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-06-06
Spring事件監(jiān)聽器@EventListener與publishEvent的使用
Spring可以通過事件監(jiān)聽器機(jī)制來處理應(yīng)用程序中的事件,本文主要介紹了Spring事件監(jiān)聽器@EventListener與publishEvent的使用,具有一定的參考價(jià)值,感興趣的可以了解一下2024-06-06
解決springboot 實(shí)體類String轉(zhuǎn)Date類型的坑
這篇文章主要介紹了解決springboot 實(shí)體類String轉(zhuǎn)Date類型的坑,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
SpringBoot自動(dòng)裝配之Condition深入講解
@Conditional表示僅當(dāng)所有指定條件都匹配時(shí),組件才有資格注冊。該@Conditional注釋可以在以下任一方式使用:作為任何@Bean方法的方法級(jí)注釋、作為任何類的直接或間接注釋的類型級(jí)別注釋@Component,包括@Configuration類、作為元注釋,目的是組成自定義構(gòu)造型注釋2023-01-01
JAVA實(shí)現(xiàn)漢字轉(zhuǎn)拼音功能代碼實(shí)例
這篇文章主要介紹了JAVA實(shí)現(xiàn)漢字轉(zhuǎn)拼音功能代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
spring boot整合scurity做簡單的登錄校驗(yàn)的實(shí)現(xiàn)
這篇文章主要介紹了spring boot整合scurity做簡單的登錄校驗(yàn)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04

