电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Springboot WebFlux集成Spring Security實現JWT認證的示例

瀏覽:37日期:2023-03-19 11:19:38
1 簡介

在之前的文章《Springboot集成Spring Security實現JWT認證》講解了如何在傳統的Web項目中整合Spring Security和JWT,今天我們講解如何在響應式WebFlux項目中整合。二者大體是相同的,主要區別在于Reactive WebFlux與傳統Web的區別。

2 項目整合

引入必要的依賴:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId></dependency><dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version></dependency>2.1 JWT工具類

該工具類主要功能是創建、校驗、解析JWT。

@Componentpublic class JwtTokenProvider { private static final String AUTHORITIES_KEY = 'roles'; private final JwtProperties jwtProperties; private String secretKey; public JwtTokenProvider(JwtProperties jwtProperties) { this.jwtProperties = jwtProperties; } @PostConstruct public void init() { secretKey = Base64.getEncoder().encodeToString(jwtProperties.getSecretKey().getBytes()); } public String createToken(Authentication authentication) { String username = authentication.getName(); Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities(); Claims claims = Jwts.claims().setSubject(username); if (!authorities.isEmpty()) { claims.put(AUTHORITIES_KEY, authorities.stream().map(GrantedAuthority::getAuthority).collect(joining(','))); } Date now = new Date(); Date validity = new Date(now.getTime() + this.jwtProperties.getValidityInMs()); return Jwts.builder().setClaims(claims).setIssuedAt(now).setExpiration(validity).signWith(SignatureAlgorithm.HS256, this.secretKey).compact(); } public Authentication getAuthentication(String token) { Claims claims = Jwts.parser().setSigningKey(this.secretKey).parseClaimsJws(token).getBody(); Object authoritiesClaim = claims.get(AUTHORITIES_KEY); Collection<? extends GrantedAuthority> authorities = authoritiesClaim == null ? AuthorityUtils.NO_AUTHORITIES: AuthorityUtils.commaSeparatedStringToAuthorityList(authoritiesClaim.toString()); User principal = new User(claims.getSubject(), '', authorities); return new UsernamePasswordAuthenticationToken(principal, token, authorities); } public boolean validateToken(String token) { try { Jws<Claims> claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token); if (claims.getBody().getExpiration().before(new Date())) {return false; } return true; } catch (JwtException | IllegalArgumentException e) { throw new InvalidJwtAuthenticationException('Expired or invalid JWT token'); } }}2.2 JWT的過濾器

這個過濾器的主要功能是從請求中獲取JWT,然后進行校驗,如何成功則把Authentication放進ReactiveSecurityContext里去。當然,如果沒有帶相關的請求頭,那可能是通過其它方式進行鑒權,則直接放過,讓它進入下一個Filter。

public class JwtTokenAuthenticationFilter implements WebFilter { public static final String HEADER_PREFIX = 'Bearer '; private final JwtTokenProvider tokenProvider; public JwtTokenAuthenticationFilter(JwtTokenProvider tokenProvider) { this.tokenProvider = tokenProvider; } @Override public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { String token = resolveToken(exchange.getRequest()); if (StringUtils.hasText(token) && this.tokenProvider.validateToken(token)) { Authentication authentication = this.tokenProvider.getAuthentication(token); return chain.filter(exchange) .subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication)); } return chain.filter(exchange); } private String resolveToken(ServerHttpRequest request) { String bearerToken = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION); if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(HEADER_PREFIX)) { return bearerToken.substring(7); } return null; }}2.3 Security的配置

這里設置了兩個異常處理authenticationEntryPoint和accessDeniedHandler。

@Configurationpublic class SecurityConfig { @Bean SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http,JwtTokenProvider tokenProvider,ReactiveAuthenticationManager reactiveAuthenticationManager) { return http.csrf(ServerHttpSecurity.CsrfSpec::disable).httpBasic(ServerHttpSecurity.HttpBasicSpec::disable).authenticationManager(reactiveAuthenticationManager).exceptionHandling().authenticationEntryPoint( (swe, e) -> { swe.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return swe.getResponse().writeWith(Mono.just(new DefaultDataBufferFactory().wrap('UNAUTHORIZED'.getBytes()))); }).accessDeniedHandler((swe, e) -> { swe.getResponse().setStatusCode(HttpStatus.FORBIDDEN); return swe.getResponse().writeWith(Mono.just(new DefaultDataBufferFactory().wrap('FORBIDDEN'.getBytes()))); }).and().securityContextRepository(NoOpServerSecurityContextRepository.getInstance()).authorizeExchange(it -> it .pathMatchers(HttpMethod.POST, '/auth/login').permitAll() .pathMatchers(HttpMethod.GET, '/admin').hasRole('ADMIN') .pathMatchers(HttpMethod.GET, '/user').hasRole('USER') .anyExchange().permitAll()).addFilterAt(new JwtTokenAuthenticationFilter(tokenProvider), SecurityWebFiltersOrder.HTTP_BASIC).build(); } @Bean public ReactiveAuthenticationManager reactiveAuthenticationManager(CustomUserDetailsService userDetailsService, PasswordEncoder passwordEncoder) { UserDetailsRepositoryReactiveAuthenticationManager authenticationManager = new UserDetailsRepositoryReactiveAuthenticationManager(userDetailsService); authenticationManager.setPasswordEncoder(passwordEncoder); return authenticationManager; }}2.4 獲取JWT的Controller

先判斷對用戶密碼進行判斷,如果正確則返回對應的權限用戶,根據用戶生成JWT,再返回給客戶端。

@RestController@RequestMapping('/auth')public class AuthController { @Autowired ReactiveAuthenticationManager authenticationManager; @Autowired JwtTokenProvider jwtTokenProvider; @PostMapping('/login') public Mono<String> login(@RequestBody AuthRequest request) { String username = request.getUsername(); Mono<Authentication> authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, request.getPassword())); return authentication.map(auth -> jwtTokenProvider.createToken(auth)); }}3 總結

其它與之前的大同小異,不一一講解了。

代碼請查看:https://github.com/LarryDpk/pkslow-samples

以上就是Springboot WebFlux集成Spring Security實現JWT認證的示例的詳細內容,更多關于Springboot WebFlux集成Spring Security的資料請關注好吧啦網其它相關文章!

標簽: Spring
相關文章:
主站蜘蛛池模板: 高压无油空压机_无油水润滑空压机_水润滑无油螺杆空压机_无油空压机厂家-科普柯超滤(广东)节能科技有限公司 | 睿婕轻钢别墅_钢结构别墅_厂家设计施工报价 | 考勤系统_人事考勤管理系统_本地部署BS考勤系统_考勤软件_天时考勤管理专家 | 聚氨酯催化剂K15,延迟催化剂SA-1,叔胺延迟催化剂,DBU,二甲基哌嗪,催化剂TMR-2,-聚氨酯催化剂生产厂家 | 安徽净化板_合肥岩棉板厂家_玻镁板厂家_安徽科艺美洁净科技有限公司 | 杭州可当科技有限公司—流量卡_随身WiFi_AI摄像头一站式解决方案 | 高清视频编码器,4K音视频编解码器,直播编码器,流媒体服务器,深圳海威视讯技术有限公司 | 建筑资质代办_工程施工资质办理_资质代办公司_北京众聚企服 | 袋式过滤器,自清洗过滤器,保安过滤器,篮式过滤器,气体过滤器,全自动过滤器,反冲洗过滤器,管道过滤器,无锡驰业环保科技有限公司 | HV全空气系统_杭州暖通公司—杭州斯培尔冷暖设备有限公司 | HDPE土工膜,复合土工膜,防渗膜价格,土工膜厂家-山东新路通工程材料有限公司 | 计算机毕业设计源码网| 自动检重秤-动态称重机-重量分选秤-苏州金钻称重设备系统开发有限公司 | 上海租车公司_上海包车_奔驰租赁_上海商务租车_上海谐焕租车 | 高速混合机_锂电混合机_VC高效混合机-无锡鑫海干燥粉体设备有限公司 | 次氯酸钠厂家,涉水级次氯酸钠,三氯化铁生产厂家-淄博吉灿化工 | 钢格板|热镀锌钢格板|钢格栅板|钢格栅|格栅板-安平县昊泽丝网制品有限公司 | 斗式提升机,斗式提升机厂家-淄博宏建机械有限公司 | 升降机-高空作业车租赁-蜘蛛车-曲臂式伸缩臂剪叉式液压升降平台-脚手架-【普雷斯特公司厂家】 | 北京京云律师事务所| 丽陂特官网_手机信号屏蔽器_Wifi信号干扰器厂家_学校考场工厂会议室屏蔽仪 | 钢衬四氟管道_钢衬四氟直管_聚四氟乙烯衬里管件_聚四氟乙烯衬里管道-沧州汇霖管道科技有限公司 | 哈希余氯测定仪,分光光度计,ph在线监测仪,浊度测定仪,试剂-上海京灿精密机械有限公司 | 硅胶布|电磁炉垫片|特氟龙胶带-江苏浩天复合材料有限公司 | 深圳美安可自动化设备有限公司,喷码机,定制喷码机,二维码喷码机,深圳喷码机,纸箱喷码机,东莞喷码机 UV喷码机,日期喷码机,鸡蛋喷码机,管芯喷码机,管内壁喷码机,喷码机厂家 | 微信小程序定制,广州app公众号商城网站开发公司-广东锋火 | 济南展厅设计施工_数字化展厅策划设计施工公司_山东锐尚文化传播有限公司 | 海外整合营销-独立站营销-社交媒体运营_广州甲壳虫跨境网络服务 焊管生产线_焊管机组_轧辊模具_焊管设备_焊管设备厂家_石家庄翔昱机械 | 铝板冲孔网,不锈钢冲孔网,圆孔冲孔网板,鳄鱼嘴-鱼眼防滑板,盾构走道板-江拓数控冲孔网厂-河北江拓丝网有限公司 | 中高频感应加热设备|高频淬火设备|超音频感应加热电源|不锈钢管光亮退火机|真空管烤消设备 - 郑州蓝硕工业炉设备有限公司 | 大流量卧式砂磨机_强力分散机_双行星双动力混合机_同心双轴搅拌机-莱州市龙跃化工机械有限公司 | 硬度计,金相磨抛机_厂家-莱州华煜众信试验仪器有限公司 | 智能化的检漏仪_气密性测试仪_流量测试仪_流阻阻力测试仪_呼吸管快速检漏仪_连接器防水测试仪_车载镜头测试仪_奥图自动化科技 | 刑事律师_深圳著名刑事辩护律师_王平聚【清华博士|刑法教授】 | 老房子翻新装修,旧房墙面翻新,房屋防水补漏,厨房卫生间改造,室内装潢装修公司 - 一修房屋快修官网 | 水质监测站_水质在线分析仪_水质自动监测系统_多参数水质在线监测仪_水质传感器-山东万象环境科技有限公司 | BHK汞灯-百科|上海熙浩实业有限公司| 深圳希玛林顺潮眼科医院(官网)│深圳眼科医院│医保定点│香港希玛林顺潮眼科中心连锁品牌 | 医院专用门厂家报价-医用病房门尺寸大全-抗菌木门品牌推荐 | 西门子气候补偿器,锅炉气候补偿器-陕西沃信机电工程有限公司 | 京港视通报道-质量走进大江南北-京港视通传媒[北京]有限公司 |