日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Security+jwt+验证码实现验证和授权

發(fā)布時(shí)間:2025/4/16 编程问答 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Security+jwt+验证码实现验证和授权 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

微服務(wù)Security+jwt+驗(yàn)證碼實(shí)現(xiàn)認(rèn)證和授權(quán)

  • 簡要介紹
  • 基本流程
  • 核心代碼
  • 測試

簡要介紹

本次博客采用Spring Security、jwt、驗(yàn)證碼的形式實(shí)現(xiàn)登錄驗(yàn)證,項(xiàng)目本身是一個(gè)前后端分離項(xiàng)目。如果你的項(xiàng)目在登陸時(shí)不需要驗(yàn)證碼,你只需要在后續(xù)的代碼中,將有關(guān)驗(yàn)證碼的過濾器刪除。
gitee倉庫連接

基本流程

1、前端請(qǐng)求后端"/captcha"驗(yàn)證碼接口,后端生成驗(yàn)證碼文本及編碼并將其存入redis緩存,然后返回驗(yàn)證碼文本(五個(gè)字符)和驗(yàn)證碼base64編碼給前端。
2、前端顯示驗(yàn)證碼圖片,用戶輸入用戶名、密碼、驗(yàn)證碼點(diǎn)擊登錄。
3、后端開啟驗(yàn)證
(1)開啟驗(yàn)證碼驗(yàn)證,走驗(yàn)證碼過濾器,如果正確則放行走下一個(gè)過濾器,如果錯(cuò)誤則拋出異常給登錄失敗過濾器,返回失敗信息給前端。
(2)開啟jwt驗(yàn)證。

a:如果請(qǐng)求沒有攜帶token,則認(rèn)為是首次登錄,jwt過濾器不做任何事情,放行走UsernamePasswordAuthenticationFilter過濾器,該過濾器會(huì)通過查數(shù)據(jù)庫驗(yàn)證用戶的身份信息決定用戶是否能登錄。如果驗(yàn)證成功會(huì)生成一個(gè)Authentication,并保存在SecurityContext(security上下文)中。Authentication包含用戶的信息及權(quán)限
b:如果請(qǐng)求中攜帶了token,走jwt過濾器,過濾器判斷jwt是否為空、攜帶信息(用戶名)是否為空,jwt是否過期,如果上述條件都正常,創(chuàng)建一個(gè)Authentication的實(shí)現(xiàn)類對(duì)象,并通過自定義的獲取用戶權(quán)限方法獲取權(quán)限,然后通過userDetailService的loadUserByUsername方法得到UserDetails對(duì)象,里面包含用戶信息和權(quán)限,調(diào)用Authentication的setUserDetails方法,最后將該Authentication對(duì)象存入到Security上下文中,后續(xù)的過濾器查詢到該Authentication,就會(huì)直接放行,比如UsernamePasswordAuthenticationFilter過濾器。

上述認(rèn)證都是由過濾器完成,因?yàn)檎J(rèn)證是有順序的,所以在security配置文件中我們要設(shè)置這三個(gè)過濾器的順序?yàn)?#xff1a;驗(yàn)證碼過濾器=》jwt過濾器=》UsernamePasswordAuthenticationFilter

.addFilterBefore(captchaFilter,UsernamePasswordAuthenticationFilter.class) .addFilterAt(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)

.addFilterAt(a,b)默認(rèn)會(huì)將a設(shè)置在b之前。

至此登錄認(rèn)證就結(jié)束了,需要注意的是,我們?cè)谡J(rèn)證的時(shí)候已經(jīng)將用戶的權(quán)限列表加入到了Authentication并放在了Security上下文中,所以后續(xù)對(duì)于資源做權(quán)限判斷時(shí)時(shí),只需要再目標(biāo)接口上加入一下注解實(shí)現(xiàn)。@PreAuthorize(“hasAuthority(‘sys:role:list’)”)
@PreAuthorize(“hasRole(‘ROLE_admin’)”)

當(dāng)請(qǐng)求該接口時(shí),security就會(huì)去Authentication中查詢有無該權(quán)限或者該角色。

核心代碼

1、驗(yàn)證碼過濾器
該過濾器用于驗(yàn)證驗(yàn)證碼是否正確。該過濾器繼承的是OncePerRequestFilter,因?yàn)槊看蔚卿浿恍枰?yàn)證一次。

package com.komorebi.security;import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.komorebi.common.CaptchaException; import com.komorebi.common.Const; import com.komorebi.utils.RedisUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;/*CaptchaFilter用于驗(yàn)證碼驗(yàn)證 * 因?yàn)轵?yàn)證碼值需要一次校驗(yàn),所以繼承OncePerRequestFilter * 自己寫的過濾器要在security配置類中配置 * */ @Slf4j @Component public class CaptchaFilter extends OncePerRequestFilter {@AutowiredRedisUtil redisUtil;@AutowiredLoginFailureHandler loginFailureHandler;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {log.info("開始驗(yàn)證碼驗(yàn)證");String url = request.getRequestURI();//只有登陸時(shí)才會(huì)驗(yàn)證驗(yàn)證碼if("/login".equals(url) && request.getMethod().equals("POST")){try{//校驗(yàn)驗(yàn)證碼validate(request);}catch (CaptchaException e){//發(fā)現(xiàn)異常,則交給登錄失敗處理器loginFailureHandler.onAuthenticationFailure(request,response,e);}}//將請(qǐng)求轉(zhuǎn)發(fā)給下一個(gè)過濾器filterChain.doFilter(request,response);}//校驗(yàn)驗(yàn)證碼邏輯private void validate(HttpServletRequest request) {String key = request.getParameter("tokens");String code = request.getParameter("code");if(StringUtils.isBlank(key) || StringUtils.isBlank(code)){throw new CaptchaException("驗(yàn)證碼信息為空");}if(!code.equals(redisUtil.hget(Const.CAPTCHA_KEY,key))){throw new CaptchaException("驗(yàn)證碼錯(cuò)誤");}//保證每個(gè)驗(yàn)證碼只使用一次:安全redisUtil.del(Const.CAPTCHA_KEY,key);} }

2、jwt過濾器

package com.komorebi.security;import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.komorebi.entity.SysUser; import com.komorebi.mapper.SysUserMapper; import com.komorebi.service.SysUserService; import com.komorebi.utils.JwtUtils; import io.jsonwebtoken.Claims; import io.jsonwebtoken.JwtException; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;//jwt認(rèn)證過濾器 @Slf4j public class JwtAuthenticationFilter extends BasicAuthenticationFilter {@AutowiredJwtUtils jwtUtils;@AutowiredUserDetailServiceImpl userDetailService;@AutowiredSysUserService sysUserService;public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {super(authenticationManager);}@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {log.info("開啟jwt認(rèn)證");String jwt = request.getHeader(jwtUtils.getHeader());if(jwt != null){Claims claim = jwtUtils.getClaimByToken(jwt);if(claim != null){String username = claim.getSubject();log.info("jwt認(rèn)證:檢查用戶名");if(username != null && SecurityContextHolder.getContext().getAuthentication() == null){SysUser sysUser = sysUserService.getByUserName(username);Long userId = sysUser.getId();UserDetails userDetails = userDetailService.loadUserByUsername(username);if(!jwtUtils.isTokenExpired(claim)){UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(username, null, userDetailService.getUserAuthority(userId));auth.setDetails(userDetails);log.info("通過jwt認(rèn)證,設(shè)置Authentication,后續(xù)過濾器放行");SecurityContextHolder.getContext().setAuthentication(auth);}}}}else {log.info("首次登陸 jwt為空");}chain.doFilter(request,response);} }

由于該過濾器我們繼承于BasicAuthenticationFilter,也可以繼承BasicAuthenticationFilter 類,并且重寫了構(gòu)造函數(shù),所以在SecurityConfig中要采用Bean注入。對(duì)應(yīng)SecurityConfig文件

@BeanJwtAuthenticationFilter jwtAuthenticationFilter() throws Exception {return new JwtAuthenticationFilter(authenticationManager());}

3、UserDetailServiceImpl
UsernamePasswordAuthenticationFilter主要功能為:用戶登錄信息驗(yàn)證,獲取用戶權(quán)限,并將上述信息封裝為UserDetails,然后生成Authentication,將UserDetails加入到Authentication中,最終將Authentication加入到security上下文中。
封裝為UserDetails的功能是通過UserDetailService實(shí)現(xiàn)的,因?yàn)閁serDetailService是接口,所以定義UserDetailServiceImpl實(shí)現(xiàn)該接口,即UserDetailServiceImpl用于驗(yàn)證用戶信息和獲取用用戶權(quán)限。

package com.komorebi.security;import com.komorebi.entity.SysUser; import com.komorebi.service.SysUserService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service;import java.util.ArrayList; import java.util.List; @Slf4j @Component public class UserDetailServiceImpl implements UserDetailsService {@AutowiredSysUserService userService;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {log.info("開始登陸驗(yàn)證,用戶名為: {}",username);SysUser user = userService.getByUserName(username);if(user == null){log.info("用戶名或密碼不正確");throw new UsernameNotFoundException("用戶名或密碼不正確");}//UserDetails是接口,User是它的一個(gè)實(shí)現(xiàn)類//將用戶密碼告訴springSecurity//剩下的認(rèn)證 就由框架Security幫我們完成return new User(user.getUsername(),user.getPassword(),getUserAuthority(user.getId()));}/*獲取用戶權(quán)限信息(角色,菜單權(quán)限)* */public List<GrantedAuthority> getUserAuthority(Long userId){//返回?fù)碛薪巧蜋?quán)限,逗號(hào)分隔String authority = userService.getUserAuthority(userId);//AuthorityUtils.commaSeparatedStringToAuthorityList將逗號(hào)分隔的字符串轉(zhuǎn)為權(quán)限列表return AuthorityUtils.commaSeparatedStringToAuthorityList(authority);} }

4、登陸成功過濾器

package com.komorebi.security;import cn.hutool.json.JSONUtil; import com.komorebi.common.Result; import com.komorebi.utils.JwtUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.stereotype.Component;import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Componentpublic class LoginSuccessHandler implements AuthenticationSuccessHandler{@AutowiredJwtUtils jwtUtils;@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {response.setContentType("application/json;charset=UTF-8");ServletOutputStream outputStream = response.getOutputStream();String username = authentication.getName();// 生成jwt,并放置到請(qǐng)求頭中String jwt = jwtUtils.generateToken(username);//將jwt放入response header中:Authorizationresponse.setHeader(jwtUtils.getHeader(), jwt);Result result = Result.success("登陸成功過濾器執(zhí)行");outputStream.write(JSONUtil.toJsonStr(result).getBytes("UTF-8"));outputStream.flush();outputStream.close();} }

這里,我們過濾器需要向前端傳遞json數(shù)據(jù),但是security是不支持return json數(shù)據(jù)的,所以我們只能通過流的方式返回?cái)?shù)據(jù)。
基本步驟:
(1)獲取reponse的字節(jié)輸出流
(2)創(chuàng)建返回對(duì)象
(3)將對(duì)象轉(zhuǎn)為字節(jié)數(shù)組輸出給response
(4)刷新緩沖區(qū),關(guān)閉流
后續(xù)的過濾器只要涉及到返回?cái)?shù)據(jù)給前端,都會(huì)使用該方法。
5、登陸失敗過濾器

package com.komorebi.security;import cn.hutool.json.JSONUtil; import com.komorebi.common.Result; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.stereotype.Component;import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;@Component public class LoginFailureHandler implements AuthenticationFailureHandler {@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {response.setContentType("application/json;charset=UTF-8");//security的返回值是重定向,對(duì)于前后端分離的項(xiàng)目需要返回json數(shù)據(jù),所以使用流的形式//因?yàn)榉祷仡愋褪莢oid,并且返回值是json類型數(shù)據(jù),所以要使用到流ServletOutputStream outputStream = response.getOutputStream();Result result = Result.fail(exception.getMessage());outputStream.write(JSONUtil.toJsonStr(result).getBytes("UTF-8"));outputStream.flush();outputStream.close();} }

6、登出成功過濾器
該處理器會(huì)返還給前端一個(gè)空的jwt,即前端下次請(qǐng)求時(shí)jwt為空,代表未登錄。如果是將jwt存在redis中,還要清除緩存。

package com.komorebi.security;import cn.hutool.json.JSONUtil; import com.komorebi.common.Const; import com.komorebi.common.Result; import com.komorebi.utils.JwtUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.stereotype.Component;import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class JwtLogoutSuccessHandler implements LogoutSuccessHandler {@AutowiredJwtUtils jwtUtils;@Overridepublic void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {System.out.println("退出成功處理器");//如果認(rèn)證的身份憑證不為空,需要手動(dòng)退出if(authentication != null){new SecurityContextLogoutHandler().logout(request,response,authentication);}response.setContentType("application/json;charset=UTF-8");ServletOutputStream outputStream = response.getOutputStream();//等處成功將jwt設(shè)置為空,因?yàn)閖wt是無狀態(tài)的只能在過期后消失response.setHeader(jwtUtils.getHeader(),"");Result result = Result.success("登出成功");outputStream.write(JSONUtil.toJsonStr(result).getBytes("UTF-8"));outputStream.flush();outputStream.close();} }

7、權(quán)限不足過濾器
該過濾器是用于處理權(quán)限不足時(shí)的情況。

package com.komorebi.security;import cn.hutool.json.JSONUtil; import com.komorebi.common.Result; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.stereotype.Component;import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class JwtAccessDeniedHandler implements AccessDeniedHandler {@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {response.setContentType("application/json;charset=UTF-8");ServletOutputStream outputStream = response.getOutputStream();//權(quán)限不足response.setStatus(HttpServletResponse.SC_FORBIDDEN);Result result = Result.fail(accessDeniedException.getMessage());outputStream.write(JSONUtil.toJsonStr(result).getBytes("UTF-8"));outputStream.flush();outputStream.close();} }

8、未認(rèn)證過濾器
該過濾器是用于處理用戶未登錄的情況。

package com.komorebi.security;import cn.hutool.json.JSONUtil; import com.komorebi.common.Result; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.stereotype.Component;import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;@Component public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {@Overridepublic void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {response.setContentType("application/json;charset=UTF-8");ServletOutputStream outputStream = response.getOutputStream();//未認(rèn)證response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);Result result = Result.fail("請(qǐng)先登錄");outputStream.write(JSONUtil.toJsonStr(result).getBytes("UTF-8"));outputStream.flush();outputStream.close();} }

9、JWT工具類

package com.komorebi.utils;import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component;import java.util.Date; @Data @Component @ConfigurationProperties(prefix = "komorebi.jwt") //通過配置文件賦值expire、secret public class JwtUtils {//兩個(gè)是參數(shù)private long expire;//保留天數(shù)private String secret;//密鑰private String header;//{header:jwt}傳給前端//生成jwtpublic String generateToken(String username){Date nowDate = new Date();Date expireDate = new Date(nowDate.getTime() * expire);return Jwts.builder().setHeaderParam("typ","JWT").setSubject(username).setIssuedAt(nowDate).setExpiration(expireDate).signWith(SignatureAlgorithm.HS256,secret).compact();}//解析jwtpublic Claims getClaimByToken(String jwt){try{return Jwts.parser().setSigningKey(secret).parseClaimsJws(jwt).getBody();}catch (Exception e){return null;}}//jwt是否過期public boolean isTokenExpired(Claims claims){//如果過期時(shí)間在當(dāng)前時(shí)間之前,就代表過期return claims.getExpiration().before(new Date());} }

expire、secret、header三個(gè)變量存放在application.yml文件中

通過該注解@ConfigurationProperties(prefix = “komorebi.jwt”)實(shí)現(xiàn)通過配置文件賦值expire、secret、header。
10、SecurityConfig
該配置類會(huì)對(duì)前面定義的所有過濾器進(jìn)行配置

package com.komorebi.config;import com.komorebi.security.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter {@AutowiredLoginSuccessHandler loginSuccessHandler;@AutowiredLoginFailureHandler loginFailureHandler;@AutowiredCaptchaFilter captchaFilter;@AutowiredJwtAccessDeniedHandler jwtAccessDeniedHandler;@AutowiredJwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;@AutowiredUserDetailsService userDetailService;@AutowiredJwtLogoutSuccessHandler jwtLogoutSuccessHandler;@BeanJwtAuthenticationFilter jwtAuthenticationFilter() throws Exception {return new JwtAuthenticationFilter(authenticationManager());}@BeanBCryptPasswordEncoder bCryptPasswordEncoder(){return new BCryptPasswordEncoder();}//Java數(shù)組初始化用的是{花括號(hào)}//URL白名單,訪問時(shí)不需要攔截private static final String [] URL_WHITELIST = {"/login","/logout","/captcha","/favicon.ico",};@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {//設(shè)置userDetail和加密方法auth.userDetailsService(userDetailService).passwordEncoder(new BCryptPasswordEncoder());}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.cors().and().csrf().disable()//登陸配置.formLogin().successHandler(loginSuccessHandler)//登陸成功處理器.failureHandler(loginFailureHandler)//登錄失敗處理器//退出.and().logout().logoutSuccessHandler(jwtLogoutSuccessHandler)//設(shè)置不生成session策略.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)//配置攔截規(guī)則.and().authorizeRequests().antMatchers(URL_WHITELIST).permitAll()//所有人都可以訪問.anyRequest().authenticated()//需要登陸,即需要認(rèn)證//異常處理器.and().exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)//沒有認(rèn)證.accessDeniedHandler(jwtAccessDeniedHandler)//沒有權(quán)限//配置自定義的過濾器=》前置過濾器.and().addFilterBefore(captchaFilter,UsernamePasswordAuthenticationFilter.class).addFilterAt(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);} }

測試

1、當(dāng)驗(yàn)證碼錯(cuò)誤時(shí)

2、驗(yàn)證碼、密碼正確時(shí)(沒有攜帶jwt登錄)

此時(shí)會(huì)返回token

3、攜帶jwt請(qǐng)求后端接口

@RestController @RequestMapping("/test") public class TestController {@AutowiredSysUserService sysUserService;@GetMapping@PreAuthorize("hasRole('admin')")public Object test(){return Result.success(sysUserService.list());} }

/test接口需要用戶具備admin角色,此處登錄的用戶具有該角色,則訪問成功。

4、對(duì)于需要某種權(quán)限或者角色才能訪問的后端接口只需要在節(jié)后上面進(jìn)行設(shè)置

(1)需要權(quán)限才能訪問

//新增@PostMapping("/save")@PreAuthorize("hasAuthority('sys:role:save')")public Result save(@Validated @RequestBody SysRole sysRole){//添加時(shí)設(shè)置create時(shí)間sysRole.setCreated(LocalDateTime.now());sysRole.setStatu(Const.STATUS_ON);sysRoleService.save(sysRole);return Result.success(sysRole);}

(2)需要用于某種角色才可以訪問

@RestController @RequestMapping("/test") public class TestController {@AutowiredSysUserService sysUserService;@GetMapping@PreAuthorize("hasRole('admin')")public Object test(){return Result.success(sysUserService.list());} }

此處登錄的用戶不具備該角色,所以會(huì)走權(quán)限不足過濾器

總結(jié)

以上是生活随笔為你收集整理的Security+jwt+验证码实现验证和授权的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。