日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

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

SpringSecurity整合springBoot、redis實(shí)現(xiàn)登錄互踢功能

瀏覽:202日期:2023-03-11 17:00:00
背景

基于我的文章——《SpringSecurity整合springBoot、redis token動(dòng)態(tài)url權(quán)限校驗(yàn)》。要實(shí)現(xiàn)的功能是要實(shí)現(xiàn)一個(gè)用戶不可以同時(shí)在兩臺(tái)設(shè)備上登錄,有兩種思路:(1)后來的登錄自動(dòng)踢掉前面的登錄。(2)如果用戶已經(jīng)登錄,則不允許后來者登錄。需要特別說明的是,項(xiàng)目的基礎(chǔ)是已經(jīng)是redis維護(hù)的session。

配置redisHttpSession

設(shè)置spring session由redis 管理。2.1去掉yml中的http session 配置,yml和注解兩者只選其一(同時(shí)配置,只有注解配置生效)。至于為什么不用yml,待會(huì)提到。

SpringSecurity整合springBoot、redis實(shí)現(xiàn)登錄互踢功能

2.2 webSecurityConfig中加入注解@EnableRedisHttpSession

SpringSecurity整合springBoot、redis實(shí)現(xiàn)登錄互踢功能

@EnableRedisHttpSession(redisNamespace = 'spring:session:myframe', maxInactiveIntervalInSeconds = 1700, flushMode = FlushMode.ON_SAVE)

登錄后發(fā)現(xiàn)redis session namespace已經(jīng)是我們命名的了

SpringSecurity整合springBoot、redis實(shí)現(xiàn)登錄互踢功能

獲取redis管理的sessionRepository

我們要限制一個(gè)用戶的登錄,自然要獲取他在系統(tǒng)中的所有session。

2.再去查看springsSession官網(wǎng)的文檔。springsession官網(wǎng) 提供文檔https://docs.spring.io/spring-session/docs/ 2.2.2.RELEASE/reference/html5/#api-findbyindexnamesessionrepository

SessionRepository實(shí)現(xiàn)也可以選擇實(shí)現(xiàn)FindByIndexNameSessionRepository

FindByIndexNameSessionRepository提供一種方法,用于查找具有給定索引名稱和索引值的所有會(huì)話

FindByIndexNameSessionRepository實(shí)現(xiàn)時(shí),可以使用方便的方法查找特定用戶的所有會(huì)話

/** * redis獲取sessionRepository * RedisIndexedSessionRepository實(shí)現(xiàn) FindByIndexNameSessionRepository接口 */ @Autowired //不加@Lazy這個(gè)會(huì)報(bào)什么循環(huán)引用... // Circular reference involving containing bean ’.RedisHttpSessionConfiguration’ @Lazy private FindByIndexNameSessionRepository<? extends Session> sessionRepository;

這里注意一點(diǎn),當(dāng)我通過yml配置redis session是,sessionRepository下面會(huì)有紅線。

SpringSecurity整合springBoot、redis實(shí)現(xiàn)登錄互踢功能

雖然不影響運(yùn)行,但是強(qiáng)迫癥,所以改用@EnableWebSecurity注解(至于為什么?我也不想知道…)。

將sessionRepository注入SpringSessionBackedSessionRegistry

是spring session為Spring Security提供的什么會(huì)話并發(fā)的會(huì)話注冊(cè)表實(shí)現(xiàn),大概是讓springSecurity幫我們?nèi)ハ拗频卿洠庖粋€(gè)sessionRepository是不行的,還得自己加點(diǎn)工具什么的。webSecurityConfig加入:

/** * 是spring session為Spring Security提供的, * 用于在集群環(huán)境下控制會(huì)話并發(fā)的會(huì)話注冊(cè)表實(shí)現(xiàn) * @return */ @Bean public SpringSessionBackedSessionRegistry sessionRegistry(){return new SpringSessionBackedSessionRegistry<>(sessionRepository); }

注:https://blog.csdn.net/qq_34136709/article/details/106012825 這篇文章說還需要加一個(gè)HttpSessionEventPublisher來監(jiān)聽session銷毀云云,大概是因?yàn)槲矣玫氖莚edis session吧,不需要這個(gè),要了之后還會(huì)報(bào)錯(cuò),啥錯(cuò)?我忘了。

新增一個(gè)session過期后的處理類

先創(chuàng)建一個(gè)CustomSessionInformationExpiredStrategy.java來處理session過期后如何通知前端的處理類,內(nèi)容如下:

public class CustomSessionInformationExpiredStrategy implements SessionInformationExpiredStrategy { @Override public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException {if (log.isDebugEnabled()) { log.debug('{} {}', event.getSessionInformation(), MessageConstant.SESSION_EVICT);}HttpServletResponse response = event.getResponse();response.setContentType(MediaType.APPLICATION_JSON_VALUE);response.setCharacterEncoding(StandardCharsets.UTF_8.toString());String responseJson = JackJsonUtil.object2String(ResponseFactory.fail(CodeMsgEnum.SESSION_EVICT, MessageConstant.SESSION_EVICT));response.getWriter().write(responseJson); }}

注:一般都是自己重新寫返回前端的信息,不會(huì)直接用框架拋出的錯(cuò)誤信息

配置到configure(HttpSecurity http)方法上

.csrf().disable()//登錄互踢.sessionManagement()//在這里設(shè)置session的認(rèn)證策略無效//.sessionAuthenticationStrategy(new ConcurrentSessionControlAuthenticationStrategy(httpSessionConfig.sessionRegistry())).maximumSessions(1).sessionRegistry(sessionRegistry()).maxSessionsPreventsLogin(false) //false表示不阻止登錄,就是新的覆蓋舊的//session失效后要做什么(提示前端什么內(nèi)容).expiredSessionStrategy(new CustomSessionInformationExpiredStrategy());

注意:https://blog.csdn.net/qq_34136709/article/details/106012825 這篇文章說session認(rèn)證的原理,我看到它是執(zhí)行了一個(gè)session的認(rèn)證策略,但是我debug對(duì)應(yīng)的代碼時(shí),發(fā)現(xiàn)

SpringSecurity整合springBoot、redis實(shí)現(xiàn)登錄互踢功能

這個(gè)session認(rèn)證策略是NullAuthenticatedSessionStrategy,而不是它說的ConcurrentSessionControlAuthenticationStrategy。就是說我需要在哪里去配置這個(gè)session 認(rèn)證策略。第一時(shí)間想到了configure(HttpSecurity http)里面配置

SpringSecurity整合springBoot、redis實(shí)現(xiàn)登錄互踢功能

結(jié)果無效。之后看到別人的代碼,想到這個(gè)策略應(yīng)該是要在登錄的時(shí)候加上去,而我們的登錄一般都需要自己重寫,自然上面的寫法會(huì)無效。于是我找到了自定義的登錄過濾器。

SpringSecurity整合springBoot、redis實(shí)現(xiàn)登錄互踢功能SpringSecurity整合springBoot、redis實(shí)現(xiàn)登錄互踢功能

然后發(fā)現(xiàn)this.setSessionAuthenticationStrategy(sessionStrategy);確實(shí)存在。

public LoginFilter(UserVerifyAuthenticationProvider authenticationManager, CustomAuthenticationSuccessHandler successHandler, CustomAuthenticationFailureHandler failureHandler, SpringSessionBackedSessionRegistry springSessionBackedSessionRegistry) {//設(shè)置認(rèn)證管理器(對(duì)登錄請(qǐng)求進(jìn)行認(rèn)證和授權(quán))this.authenticationManager = authenticationManager;//設(shè)置認(rèn)證成功后的處理類this.setAuthenticationSuccessHandler(successHandler);//設(shè)置認(rèn)證失敗后的處理類this.setAuthenticationFailureHandler(failureHandler);//配置session認(rèn)證策略(將springSecurity包裝redis Session作為參數(shù)傳入)ConcurrentSessionControlAuthenticationStrategy sessionStrategy = newConcurrentSessionControlAuthenticationStrategy(springSessionBackedSessionRegistry);//最多允許一個(gè)sessionsessionStrategy.setMaximumSessions(1);this.setSessionAuthenticationStrategy(sessionStrategy);//可以自定義登錄請(qǐng)求的urlsuper.setFilterProcessesUrl('/myLogin'); }

啟動(dòng) 后就發(fā)現(xiàn)session認(rèn)證策略已經(jīng)改為我們?cè)O(shè)定的策略了。

完整的webSecurityConfig如下:

@Configuration@EnableWebSecurity//RedisFlushMode有兩個(gè)參數(shù):ON_SAVE(表示在response commit前刷新緩存),IMMEDIATE(表示只要有更新,就刷新緩存)//yml和注解兩者只選其一(同時(shí)配置,只有注解配置生效)@EnableRedisHttpSession(redisNamespace = 'spring:session:myframe', maxInactiveIntervalInSeconds = 5000, flushMode = FlushMode.ON_SAVE)public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserVerifyAuthenticationProvider authenticationManager;//認(rèn)證用戶類 @Autowired private CustomAuthenticationSuccessHandler successHandler;//登錄認(rèn)證成功處理類 @Autowired private CustomAuthenticationFailureHandler failureHandler;//登錄認(rèn)證失敗處理類 @Autowired private MyFilterInvocationSecurityMetadataSource securityMetadataSource;//返回當(dāng)前URL允許訪問的角色列表 @Autowired private MyAccessDecisionManager accessDecisionManager;//除登錄登出外所有接口的權(quán)限校驗(yàn) /** * redis獲取sessionRepository * RedisIndexedSessionRepository實(shí)現(xiàn) FindByIndexNameSessionRepository接口 */ @Autowired //不加@Lazy這個(gè)會(huì)報(bào)什么循環(huán)引用... // Circular reference involving containing bean ’.RedisHttpSessionConfiguration’ @Lazy private FindByIndexNameSessionRepository<? extends Session> sessionRepository; /** * 是spring session為Spring Security提供的, * 用于在集群環(huán)境下控制會(huì)話并發(fā)的會(huì)話注冊(cè)表實(shí)現(xiàn) * @return */ @Bean public SpringSessionBackedSessionRegistry sessionRegistry(){return new SpringSessionBackedSessionRegistry<>(sessionRepository); } /** * 密碼加密 * @return */ @Bean @ConditionalOnMissingBean(PasswordEncoder.class) public PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder(); } /** * 配置 HttpSessionIdResolver Bean * 登錄之后將會(huì)在 Response Header x-auth-token 中 返回當(dāng)前 sessionToken * 將token存儲(chǔ)在前端 每次調(diào)用的時(shí)候 Request Header x-auth-token 帶上 sessionToken */ @Bean public HttpSessionIdResolver httpSessionIdResolver() {return HeaderHttpSessionIdResolver.xAuthToken(); } /** * Swagger等靜態(tài)資源不進(jìn)行攔截 */ @Override public void configure(WebSecurity web) {web.ignoring().antMatchers('/*.html','/favicon.ico','/**/*.html','/**/*.css','/**/*.js','/error','/webjars/**','/resources/**','/swagger-ui.html','/swagger-resources/**','/v2/api-docs'); } @Override protected void configure(HttpSecurity http) throws Exception {http.authorizeRequests()//配置一些不需要登錄就可以訪問的接口,這里配置失效了,放到了securityMetadataSource里面//.antMatchers('/demo/**', '/about/**').permitAll()//任何尚未匹配的URL只需要用戶進(jìn)行身份驗(yàn)證.anyRequest().authenticated()//登錄后的接口權(quán)限校驗(yàn).withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() { @Override public <O extends FilterSecurityInterceptor> O postProcess(O object) {object.setAccessDecisionManager(accessDecisionManager);object.setSecurityMetadataSource(securityMetadataSource);return object; }}).and()//配置登出處理.logout().logoutUrl('/logout').logoutSuccessHandler(new CustomLogoutSuccessHandler()).clearAuthentication(true).and()//用來解決匿名用戶訪問無權(quán)限資源時(shí)的異常.exceptionHandling().authenticationEntryPoint(new CustomAuthenticationEntryPoint())//用來解決登陸認(rèn)證過的用戶訪問無權(quán)限資源時(shí)的異常.accessDeniedHandler(new CustomAccessDeniedHandler()).and()//配置登錄過濾器.addFilter(new LoginFilter(authenticationManager, successHandler, failureHandler, sessionRegistry())).csrf().disable()//登錄互踢.sessionManagement()//在這里設(shè)置session的認(rèn)證策略無效//.sessionAuthenticationStrategy(new ConcurrentSessionControlAuthenticationStrategy(httpSessionConfig.sessionRegistry())).maximumSessions(1).sessionRegistry(sessionRegistry()).maxSessionsPreventsLogin(false) //false表示不阻止登錄,就是新的覆蓋舊的//session失效后要做什么(提示前端什么內(nèi)容).expiredSessionStrategy(new CustomSessionInformationExpiredStrategy());//配置頭部http.headers().contentTypeOptions().and().xssProtection().and()//禁用緩存.cacheControl().and().httpStrictTransportSecurity().and()//禁用頁面鑲嵌frame劫持安全協(xié)議 // 防止iframe 造成跨域.frameOptions().disable(); }}

其他

@Lazyprivate FindByIndexNameSessionRepository<? extends Session> sessionRepository;

至于這個(gè)不加@lazy會(huì)什么循環(huán)引用的問題,我就真的不想理會(huì)了。看了好長時(shí)間,都不知道誰和誰發(fā)生了循環(huán)引用。。。。。

到此這篇關(guān)于SpringSecurity整合springBoot、redis——實(shí)現(xiàn)登錄互踢的文章就介紹到這了,更多相關(guān)SpringSecurity登錄互踢內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩一区二区三免费高清在线观看 | 欧美网站在线| 91综合网人人| 久久av国产紧身裤| 激情国产在线| 久久久久亚洲| 国产免费成人| 久久av偷拍| 99国产精品私拍| 欧美影院精品| 九一国产精品| 91看片一区| 最新国产精品视频| 91日韩免费| 国产午夜一区| 四虎成人av| 国产高清久久| 亚洲深夜福利在线观看| 日韩三级久久| 色综合五月天| 日韩欧美国产精品综合嫩v| 日韩一区三区| 激情视频一区二区三区| 欧美亚洲国产激情| 国产免费成人| 91精品视频一区二区| 日韩欧美三级| 欧美亚洲国产精品久久| 国产不卡精品| 亚洲天堂av资源在线观看| 久久激五月天综合精品| 久久精品女人| 日韩激情av在线| 国产精品美女午夜爽爽| 亚洲精品伊人| 亚洲精品观看| 视频在线观看一区二区三区| 日本不卡视频在线| 久久永久免费| 欧美性感美女一区二区| 蜜桃91丨九色丨蝌蚪91桃色| 国产精品videossex久久发布 | 在线视频精品| 婷婷综合国产| 久久精品色播| 亚洲专区欧美专区| 国产精品mv在线观看| 国产理论在线| 亚洲影院天堂中文av色| 久久免费福利| 黄色亚洲在线| 国产精品欧美日韩一区| 国产一区久久| 91精品国产经典在线观看 | 日韩欧美久久| 成人精品国产亚洲| 亚洲九九精品| 久久蜜桃精品| 亚洲日本欧美| 精品丝袜久久| 亚洲视频二区| 亚洲国产福利| 日韩中出av| 亚洲综合在线电影| 国产日韩欧美在线播放不卡| 国内精品99| 久久一区视频| 欧美日韩国产欧| 麻豆精品久久久| 亚洲国产日韩欧美在线| 精品资源在线| 亚洲精品乱码| 久久精品免费一区二区三区| 国产日韩欧美中文在线| 午夜国产欧美理论在线播放| 国产不卡精品| 欧美日韩一区二区三区四区在线观看 | 久久中文字幕二区| 国产欧美一区二区三区米奇| 伊人影院久久| 日韩免费av| 国产乱码精品一区二区三区四区| 夜夜嗨网站十八久久| 日本一区二区高清不卡| 日韩精品成人在线观看| 欧美aa国产视频| 欧美交a欧美精品喷水| 视频一区欧美精品| 久久黄色影院| 麻豆视频久久| 亚洲欧洲一区| 日韩高清中文字幕一区二区| 国产伦理一区| 日韩中文字幕一区二区高清99| 日韩一区二区久久| 久久久久.com| 精品国产91| 国产精品夜夜夜| 91久久精品无嫩草影院| 久久亚洲欧洲| 亚洲精品一区二区妖精| 成人美女视频| 国产伊人久久| 毛片不卡一区二区| 国产精品一线| 日韩精品一二三四| 午夜一区在线| 伊人久久成人| 精品一区亚洲| 亚州av乱码久久精品蜜桃| 欧美精品资源| 成人免费电影网址| 欧美亚洲日本精品| 女生影院久久| 色在线视频观看| 日韩理论视频| 新版的欧美在线视频| 都市激情国产精品| av最新在线| 亚洲欧洲高清| 成人在线视频中文字幕| 精品久久在线| 日本久久黄色| 精品欧美一区二区三区在线观看| 精品欧美视频| 国产精品毛片一区二区在线看| 国产精品a级| 欧美黄页在线免费观看| 精品一区视频| 国产aⅴ精品一区二区三区久久| 精品日韩在线| 日韩中文影院| 精品中文字幕一区二区三区av| 欧美va天堂| 午夜欧美精品| 亚洲国产专区校园欧美| 一级欧洲+日本+国产| 久色成人在线| 91精品啪在线观看国产爱臀| 日本欧美韩国一区三区| 国产精品黄网站| 精品国产日韩欧美精品国产欧美日韩一区二区三区 | 国产亚洲观看| 国产精品a级| 国产精品白丝久久av网站| 久久精品国产99国产| 高清一区二区三区av| 欧美日韩中文一区二区| 国产亚洲一级| 91亚洲无吗| 久久影视三级福利片| 日韩另类视频| 男人操女人的视频在线观看欧美| 亚洲精品黄色| 精品一区二区三区中文字幕视频 | 亚洲大全视频| 99久久亚洲精品蜜臀| 免费不卡中文字幕在线| 中文一区一区三区免费在线观| 日韩国产在线一| 国产精品精品| 在线综合亚洲| 国产亚洲高清一区| av综合电影网站| 一区二区自拍| 国产欧美日韩精品高清二区综合区 | 日韩精品视频在线看| 免费观看在线色综合| 69精品国产久热在线观看| 国产999精品在线观看| 午夜精品婷婷| 国产麻豆一区二区三区 | 日本不卡一二三区黄网| 最新亚洲国产| 成人在线超碰| 九九精品调教| 蜜桃91丨九色丨蝌蚪91桃色| 水野朝阳av一区二区三区| 欧美一区三区| 国产主播一区| 午夜一区在线| 成人精品高清在线视频| 丝袜美腿高跟呻吟高潮一区| 久久久免费人体| 视频一区在线视频| 精品欧美日韩精品| 久久亚洲精品伦理| 精品国产精品久久一区免费式| 欧美一级精品| 国产精品观看| 亚洲二区免费| 视频一区国产视频| 视频在线不卡免费观看| 蜜臀精品一区二区三区在线观看 | 国产精品欧美在线观看| 成人免费网站www网站高清| 黄色成人在线网址| 日本不卡高清| 国产精品密蕾丝视频下载| 国产精品一区毛片|