国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringBoot2.3集成Spring Security(二) JWT認證

這篇具有很好參考價值的文章主要介紹了SpringBoot2.3集成Spring Security(二) JWT認證。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

項目背景

緊接上文,我們已經(jīng)完成了 SpringBoot中集成Spring Security,并且用戶名帳號和密碼都是從數(shù)據(jù)庫中獲取。但是這種方式還是不能滿足現(xiàn)在的開發(fā)需求。

使用JWT的好處:

  1. 無狀態(tài)認證:JWT本身包含了認證信息和聲明,服務(wù)器不需要在會話中保存任何狀態(tài)。這樣使得應(yīng)用程序可以更加容易的擴展,并且更適合分布式部署和微服務(wù)架構(gòu)。
  2. 跨域支持:由于JWT在HTTP頭部中進行傳輸,因此它可以輕松的支持跨域請求。
  3. 靈活性:JWT可以包含任意數(shù)量的聲明,這些聲明可以用來傳遞用戶、角色、或者其他相關(guān)的元數(shù)據(jù)。這些數(shù)據(jù)可以在服務(wù)器端和客戶端之間共享,從而簡化了授權(quán)和訪問控制管理。
  4. 安全性:JWT使用數(shù)字簽名或者加密算法來驗證其完整性和真實性。這確保了JWT在傳輸過程中不會被篡改或偽造。

JWT(Json Web Tokens)

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDS

翻譯:JSON Web Token (JWT) 是一個開放標準 (RFC 7519),它定義了一種緊湊且自包含的方式,用于在各方之間安全地傳輸信息作為 JSON 對象。 此信息可以驗證和信任,因為它是數(shù)字簽名的。 JWT 可以使用密鑰(使用 HMAC 算法)或使用 RSA 或 ECDSA 的公鑰/私鑰對進行簽名。

JWT組成

  • header: 存放簽名的生成算法。
  • payload:存放用戶名、token的生成時間和過期時間。
  • signature:以header和payload生成的簽名,一旦header和payload被篡改,驗證將失敗。
    可以在該網(wǎng)站上進行解析:https://jwt.io/
    SpringBoot2.3集成Spring Security(二) JWT認證

Spring Security集成JWT

maven引入

 		<dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>

首先不論是不是Spring Security中集成JWT,我們得先有個工具類。這個工具類的主要內(nèi)容是什么呢?
創(chuàng)建JWT、驗證JWT、 解析JWT

步驟一:

JwtUtils工具類

/**
 * jwt工具類
 *
 * @author caojing
 * @since 2023/6/14
 */
public class JwtUtils {

    /**
     * token過期時間
     */
    public static final long EXPIRE = 1000 * 60 * 60 * 24;

    /**
     * 秘鑰
     */
    public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO";

    /**
     * 生成token字符串的方法
     *
     * @param id
     * @param nickname
     * @return
     */
    public static String getJwtToken(String id, String nickname) {
        String jwtToken = Jwts.builder().setHeaderParam("typ", "JWT").setHeaderParam("alg", "HS256")
                .setSubject("guli-user").setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
                //設(shè)置token主體部分 ,存儲用戶信息
                .claim("id", id)
                .claim("nickname", nickname)
                .signWith(SignatureAlgorithm.HS256, APP_SECRET).compact();

        return jwtToken;
    }

    /**
     * 判斷token是否存在與有效
     *
     * @param jwtToken
     * @return
     */
    public static boolean checkToken(String jwtToken) {
        if (StringUtils.isEmpty(jwtToken)) {
            return false;
        }
        try {
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 判斷token是否存在與有效
     *
     * @param request
     * @return
     */
    public static boolean checkToken(HttpServletRequest request) {
        try {
            String jwtToken = request.getHeader("Authorization");
            if (StringUtils.isEmpty(jwtToken)) {
                return false;
            }
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 根據(jù)token字符串獲取會員id
     *
     * @param request
     * @return
     */
    public static String getUserIdByJwtToken(HttpServletRequest request) {
        String jwtToken = request.getHeader("Authorization");
        if (StringUtils.isEmpty(jwtToken)) {
            return "";
        }
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        Claims claims = claimsJws.getBody();
        return (String) claims.get("id");
    }

    /**
     * 驗證jwt
     */
    public static Claims verifyJwt(String token) {
        Claims claims;
        try {
            //得到DefaultJwtParser
            claims = Jwts.parser()
                    //設(shè)置簽名的秘鑰
                    .setSigningKey(APP_SECRET)
                    .parseClaimsJws(token).getBody();
        } catch (Exception e) {
            e.printStackTrace();
            claims = null;
        }//設(shè)置需要解析的jwt
        return claims;
    }
}

我們可以設(shè)想下這么一個流程:
前端在請求頭中設(shè)置 Authorization參數(shù),后臺再進入到controller之前,會走一個過濾器對header中的Authorization參數(shù)進行校驗,也就是利用JWTUtils對token進行解析。
1.通過校驗:模擬 spring Security 登錄成功,把token值塞到一個變量里面。
2.未通過校驗:繼續(xù)走spring Security的驗證流程(理論上會拋出異常)
注意以上我們分析的關(guān)鍵字:過濾器
因此,我們新建一個JwtAuthenticationTokenFilter 類繼承OncePerRequestFilter 。
繼承 OncePerRequestFilter 的原因:

  • 確保在一次請求中只執(zhí)行一次過濾操作。OncePerRequestFilter是Spring框架提供的一個過濾器基類,它確保每個請求只通過一次,而不會重復(fù)執(zhí)行過濾邏輯。
  • 當客戶端發(fā)送請求時,過濾器鏈會按照配置的順序?qū)φ埱筮M行過濾。如果一個過濾器沒有繼承OncePerRequestFilter,它可能會在請求鏈中的多個位置執(zhí)行,導(dǎo)致重復(fù)處理請求的問題。
  • 繼承OncePerRequestFilter可以確保JwtAuthenticationTokenFilter在整個過濾器鏈中的每個請求中只執(zhí)行一次,避免了多次處理同一個請求的問題。這對于執(zhí)行基于JWT的身份驗證和授權(quán)邏輯非常重要,因為它確保只有在一次請求中進行一次JWT的驗證和解析,避免了不必要的性能開銷和潛在的安全問題。

總結(jié)來說,JwtAuthenticationTokenFilter繼承OncePerRequestFilter是為了保證它在過濾器鏈中的每個請求中只執(zhí)行一次,避免了重復(fù)處理請求的問題,確保了JWT身份驗證和授權(quán)邏輯的準確性和性能。

步驟二

將jwtFilter添加到Spring Security 過濾器中

JwtAuthenticationTokenFilter

/**
 * token過濾器 驗證token有效性
 * 判斷用戶是否有效走 MyUserDetailService的 loadUserByUsername 方法
 *
 * @author caojing
 */
@Slf4j
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private RedisUtils redisUtils;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        // 從請求頭中獲取token
        String authToken = request.getHeader("Authorization");
        // 截取token
        if (authToken != null) {
            //驗證token,獲取token中的username
            Claims claims = JwtUtils.verifyJwt(authToken);
            if (claims == null) {
                throw new ServletException("token異常,請重新登錄");
            }
            //從redis 獲取緩存
            String redisKey = JwtUtils.getUserIdByJwtToken(request);
            UserBean userBean = redisUtils.getCacheObject(redisKey);
            //重新設(shè)置token的失效時間
            redisUtils.setCacheObject(redisKey, userBean, 30, TimeUnit.MINUTES);
            if (userBean != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                //獲取到值,相當于手動把session值設(shè)置到此次request中,后續(xù)就會認為已經(jīng)登錄,不做登錄校驗
                UsernamePasswordAuthenticationToken authenticationToken =
                        new UsernamePasswordAuthenticationToken(userBean, null, userBean.getAuthorities());
                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
        }
        //繼續(xù)下一個過濾器
        chain.doFilter(request, response);
    }
}

JwtAuthenticationTokenFilter添加到ScurityConfig類中

/**
 * Spring Security 配置類
 *
 * @author caojing
 * @since 2023/6/14
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private MyUserDetailService userDetailService;
    @Autowired
    private JwtAuthenticationTokenFilter JwtAuthenticationTokenFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http// 基于token,所以不需要session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .addFilterBefore(JwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
//        auth.inMemoryAuthentication()
//                .passwordEncoder(new BCryptPasswordEncoder())
//                .withUser("user").password(encoder.encode("123456")).roles("USER");
        auth.userDetailsService(userDetailService).passwordEncoder(new BCryptPasswordEncoder());
    }
}

說明:利用addFilterBefore方法,把jwt認證放到UsernamePasswordAuthenticationFilter過濾器之前。為什么要放到這里,我們下一篇文章會說。

步驟三

怎么把驗證交給Spring Security

基本工作已經(jīng)做完。我們還剩下一個獲取token的controller。
想一想這個controller應(yīng)該有什么功能?
沒有使用spring Security之前,我們是不是在login獲取用戶輸入的帳號名和密碼,然后根據(jù)帳號名從數(shù)據(jù)庫查詢出來對應(yīng)的用戶信息。然后對比密碼(加密后)是否正確。
使用了Spring Security之后,思考一下,哪些能用,哪些需要替換。

  1. 帳號名密碼的獲取肯定是要繼續(xù)用的。
  2. 認證移動到了MyUserDetailService中認證,也就是使用Spring Security的 DaoAuthenticationProvider進行認證。所以原先的認證需要刪除替換成DaoAuthenticationProvider認證。

上面第一個問題好解決,那么第二個問題該如何實現(xiàn)呢?
先說結(jié)果:

使用AuthenticationManagerauthenticate方法進行認證。

如何找到這個入口?
我們現(xiàn)在已知的類是DaoAuthenticationProvider,所以先從這個類開始。先看下這個類是實現(xiàn)AuthenticationProvider接口。先說一下這個接口的2個方法構(gòu)成:

	// ~ Methods
	// ========================================================================================================

	/**
	 * Performs authentication with the same contract as
	 * {@link org.springframework.security.authentication.AuthenticationManager#authenticate(Authentication)}
	 * .
	 * 
	 * @param authentication the authentication request object.
	 *
	 * @return a fully authenticated object including credentials. May return
	 * <code>null</code> if the <code>AuthenticationProvider</code> is unable to support
	 * authentication of the passed <code>Authentication</code> object. In such a case,
	 * the next <code>AuthenticationProvider</code> that supports the presented
	 * <code>Authentication</code> class will be tried.
	 *
	 * @throws AuthenticationException if authentication fails.
	 */
	Authentication authenticate(Authentication authentication)
			throws AuthenticationException;

	/**
	 * Returns <code>true</code> if this <Code>AuthenticationProvider</code> supports the
	 * indicated <Code>Authentication</code> object.
	 * <p>
	 * Returning <code>true</code> does not guarantee an
	 * <code>AuthenticationProvider</code> will be able to authenticate the presented
	 * instance of the <code>Authentication</code> class. It simply indicates it can
	 * support closer evaluation of it. An <code>AuthenticationProvider</code> can still
	 * return <code>null</code> from the {@link #authenticate(Authentication)} method to
	 * indicate another <code>AuthenticationProvider</code> should be tried.
	 * </p>
	 * <p>
	 * Selection of an <code>AuthenticationProvider</code> capable of performing
	 * authentication is conducted at runtime the <code>ProviderManager</code>.
	 * </p>
	 * 
	 * @param authentication
	 *
	 * @return <code>true</code> if the implementation can more closely evaluate the
	 * <code>Authentication</code> class presented
	 */
	boolean supports(Class<?> authentication);

這邊重點注意2句話:

  1. Performs authentication with the same contract as * {@link org.springframework.security.authentication.AuthenticationManager#authenticate(Authentication)}
    翻譯
    執(zhí)行的身份認證和AuthenticationManager#authenticate這個方法具有相同的合同?
    黑人問號臉?換個說人話的:
    合同 = 契約。
    軟件開發(fā)中 contract一般都翻譯成契約的意思。而且契約在軟件開發(fā)中特制:定義了功能、接口或方法應(yīng)該具有的行為和特征的規(guī)范。當兩個功能或組件具有相同的契約時,它們在執(zhí)行特定操作時遵循相同的規(guī)則和約定。也就是俗稱約定。
    人話:
    這個方法和AuthenticationManager#authenticate(Authentication) 具有相同的認證規(guī)則和約定
  2. Selection of an AuthenticationProvider capable of performing authentication is conducted at runtime the ProviderManager.
    翻譯:
    選擇一個AuthenticationProvider能夠執(zhí)行身份校驗是在ProviderManager運行執(zhí)行期間?
    人話:
    在ProviderManager運行執(zhí)行期間來使用該方法判斷AuthenticationProvider是否能執(zhí)行身份校驗

這2個方法都提到了一個類:ProviderManager。所以下一步我們看看這個類。
有點長。。。。。。。。
直接看AuthenticationManager這個接口吧:

/**
 * Processes an {@link Authentication} request.
 *
 * @author Ben Alex
 */
public interface AuthenticationManager {
	// ~ Methods
	// ========================================================================================================

	/**
	 * Attempts to authenticate the passed {@link Authentication} object, returning a
	 * fully populated <code>Authentication</code> object (including granted authorities)
	 * if successful.
	 * <p>
	 * An <code>AuthenticationManager</code> must honour the following contract concerning
	 * exceptions:
	 * <ul>
	 * <li>A {@link DisabledException} must be thrown if an account is disabled and the
	 * <code>AuthenticationManager</code> can test for this state.</li>
	 * <li>A {@link LockedException} must be thrown if an account is locked and the
	 * <code>AuthenticationManager</code> can test for account locking.</li>
	 * <li>A {@link BadCredentialsException} must be thrown if incorrect credentials are
	 * presented. Whilst the above exceptions are optional, an
	 * <code>AuthenticationManager</code> must <B>always</B> test credentials.</li>
	 * </ul>
	 * Exceptions should be tested for and if applicable thrown in the order expressed
	 * above (i.e. if an account is disabled or locked, the authentication request is
	 * immediately rejected and the credentials testing process is not performed). This
	 * prevents credentials being tested against disabled or locked accounts.
	 *
	 * @param authentication the authentication request object
	 *
	 * @return a fully authenticated object including credentials
	 *
	 * @throws AuthenticationException if authentication fails
	 */
	Authentication authenticate(Authentication authentication)
			throws AuthenticationException;
}

該類只有一個方法:authenticate。
解釋:
嘗試對傳遞的 Authentication 對象進行身份驗證,如果成功則返回一個完全填充的 Authentication 對象(包括授予的權(quán)限)。。。。。。。。。
人話:
對我們傳入的Authentication對象進行身份認證,通過以后會返回Authentication 對象。
簡而言之。這個類AuthenticationManager 就是我們具體身份認證的入口了,但這是一個接口,具體的實現(xiàn)類是通過默認的ProviderManager實現(xiàn)。
繼續(xù)看ProviderManager中的authenticate方法:

public Authentication authenticate(Authentication authentication)
			throws AuthenticationException {
		Class<? extends Authentication> toTest = authentication.getClass();
		AuthenticationException lastException = null;
		AuthenticationException parentException = null;
		Authentication result = null;
		Authentication parentResult = null;
		boolean debug = logger.isDebugEnabled();

		for (AuthenticationProvider provider : getProviders()) {
			if (!provider.supports(toTest)) {
				continue;
			}

			if (debug) {
				logger.debug("Authentication attempt using "
						+ provider.getClass().getName());
			}

			try {
				result = provider.authenticate(authentication);

				if (result != null) {
					copyDetails(authentication, result);
					break;
				}
			}
			catch (AccountStatusException | InternalAuthenticationServiceException e) {
				prepareException(e, authentication);
				// SEC-546: Avoid polling additional providers if auth failure is due to
				// invalid account status
				throw e;
			} catch (AuthenticationException e) {
				lastException = e;
			}
		}
......
}

我這里只貼出來部分代碼:我們可以看到代碼的主要結(jié)構(gòu)是一個for循環(huán)。循環(huán)的內(nèi)容是啥呢?是AuthenticationProvider的實現(xiàn)類。循環(huán)干什么呢?

  1. 根據(jù)AuthenticationProvider中的provider方法判斷是否支持驗證當前的authentication ,具體行:189行。
  2. 判斷具體的身份權(quán)限交給AuthenticationProviderauthenticate方法,具體行:199行

解釋一下第一句話:
AuthenticationProviderauthentication 都是接口,并不是具體的實現(xiàn)類,所以看來比較抽象。因此,我就拿用戶名密碼登錄方式舉例。
在用戶名和密碼登錄模式中 AuthenticationProvider的具體實現(xiàn)類AbstractUserDetailsAuthenticationProvider
authentication 的具體實現(xiàn)類是UsernamePasswordAuthenticationToken。那么驗證身份流程就變成了
ProviderManager#authentication -> AbstractUserDetailsAuthenticationProvider#supports->AbstractUserDetailsAuthenticationProvider#authenticate->return UsernamePasswordAuthenticationToken
具體時序圖如下所示:
SpringBoot2.3集成Spring Security(二) JWT認證
基于以上的流程,我們不難知道在login中需要調(diào)用authenticationManager#authenticate方法進行認證了

如何引入AuthenticationManager?

看下配置類中繼承的類WebSecurityConfigurerAdapter
其中有個方法:

	/**
	 * Override this method to expose the {@link AuthenticationManager} from
	 * {@link #configure(AuthenticationManagerBuilder)} to be exposed as a Bean. For
	 * example:
	 *
	 * <pre>
	 * &#064;Bean(name name="myAuthenticationManager")
	 * &#064;Override
	 * public AuthenticationManager authenticationManagerBean() throws Exception {
	 *     return super.authenticationManagerBean();
	 * }
	 * </pre>
	 *
	 * @return the {@link AuthenticationManager}
	 * @throws Exception
	 */
	public AuthenticationManager authenticationManagerBean() throws Exception {
		return new AuthenticationManagerDelegator(authenticationBuilder, context);
	}

這很好理解吧,不需要翻譯了。
Logservice 代碼如下:

/**
 * 登錄接口
 *
 * @author caojing
 * @since 2023/6/15
 */
@Slf4j
@Service
public class LoginService {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisUtils redisUtils;

    public ResponseBean<String> login(String username, String password) {
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(username, password);
        Authentication authentication = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
        //這邊可以獲取用戶信息.這里getPrincipal和 JwtAuthenticationTokenFilter類中 完成token驗證之后
        //new UsernamePasswordAuthenticationToken 塞進去的值
        UserBean userBean = (UserBean) authentication.getPrincipal();
        log.info("用戶信息:{}", JSON.toJSONString(userBean));
        String token = JwtUtils.getJwtToken(String.valueOf(userBean.getId()), username);
        //每次登錄都獲取最新的值,
        redisUtils.setCacheObject(String.valueOf(userBean.getId()), userBean, 30, TimeUnit.MINUTES);
        return new ResponseBean<>(HttpStatus.OK.value(), "獲取成功", token);
    }
}

SecurityConfig配置類增加

/**
 * Spring Security 配置類
 *
 * @author caojing
 * @since 2023/6/14
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//......................
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

啟動項目

訪問地址:http://127.0.0.1:8889/token
SpringBoot2.3集成Spring Security(二) JWT認證
測試一下token值是否有效。
先測試不帶Authorization的請求:http://127.0.0.1:8889/test
SpringBoot2.3集成Spring Security(二) JWT認證
Authorization的請求:http://127.0.0.1:8889/test
SpringBoot2.3集成Spring Security(二) JWT認證

總結(jié)

思路:
整體思路分2個部分:

  • 登錄認證獲取token
    提供一個controller,將controller的地址加到spring Security 的config中不做權(quán)限控制,訪問該controller,將用戶名和密碼的判斷交給spring Security 的userDetailService處理,根據(jù)處理的返回結(jié)果決定是否生成對應(yīng)的token值。

    • 如何交給Spring Security 處理認證過程:authenticationManager.authenticate()。具體是怎么找到這個入口的,詳情可以看步驟三。
  • 接口認證token值

    • 加入JWT生成的工具類
    • Spring Security 提供多種認證方式,但我們需要熟悉的是UsernamePasswordAuthenticationFilter。剩下的認證方式了解即可。
    • 在了解了Spring Security的幾種認證方式之后,我們需要考慮將自定義的jwtFilter加入到Srping Security的過濾器中。對應(yīng)上面的步驟二。
    • 步驟二完成以后,當token值存在的時候,會把用戶信息轉(zhuǎn)化成UsernamePasswordAuthenticationToken,其實也不是非要這個類,任何一個實現(xiàn)Authentication即接口的類都可以。然后通過SecurityContextHolder.getContext().setAuthentication()方法,將用戶信息設(shè)置到SecurityContextHolder
      下面是一張Spring Security的過濾器的鏈路圖,基本上Spring Security 都是圍繞著這幾個過濾器進行一些功能。比如后續(xù)的異常、權(quán)限控制(選舉策略)都是在過濾器中實現(xiàn)。具體內(nèi)容咱們下個章節(jié)繼續(xù)聊。
      SpringBoot2.3集成Spring Security(二) JWT認證

習(xí)題:

  1. 為什么通過SecurityContextHolder.getContext().setAuthentication()方法就可以實現(xiàn)登錄了?;蛘哒fSecurityContextHolder到底有什么用。
  2. Spring Security中主要分為權(quán)限和認證,認證已經(jīng)講過了,那么權(quán)限是如何控制的?(提示:也是過濾器,涉及的幾個類SecurityMetadataSource 、GrantedAuthority、AccessDecisionManager
  3. 能否找到Spring Security中的大部分的過濾器?

下一篇主要內(nèi)容是稍微介紹下Spring Security的源碼,順帶解決習(xí)題中的幾個問題。
上一篇文章地址:SpringBoot2.3集成Spring Security(一)文章來源地址http://www.zghlxwxcb.cn/news/detail-500448.html

到了這里,關(guān)于SpringBoot2.3集成Spring Security(二) JWT認證的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 3-1. SpringBoot項目集成【用戶身份認證】實戰(zhàn) 【技術(shù)選型篇】基于Session、Token、JWT怎么選?

    3-1. SpringBoot項目集成【用戶身份認證】實戰(zhàn) 【技術(shù)選型篇】基于Session、Token、JWT怎么選?

    通過第二章2-2. SpringBoot API開發(fā)詳解 --SpringMVC注解+封裝結(jié)果+支持跨域+打包,我們實現(xiàn)了基于SpringBoot項目的 API接口開發(fā) ,并實現(xiàn) API結(jié)果統(tǒng)一封裝、支持跨域請求 等等功能,接下來開始第三章,主要做用戶身份認證,主要實現(xiàn)一套 統(tǒng)一鑒權(quán)的用戶身份認證的機制 。 我已經(jīng)提

    2024年01月22日
    瀏覽(26)
  • 3-3. SpringBoot項目集成【用戶身份認證】實戰(zhàn) 【全流程篇】基于JWT+雙重檢查的登錄+登出+攔截器

    書接上文 實戰(zhàn)核心篇,我們已經(jīng) 把JWT的核心代碼實現(xiàn)了! 文中不止是代碼實現(xiàn),更是使用到了設(shè)計原則,提升大家的內(nèi)功心法。并且拋轉(zhuǎn)引玉的實現(xiàn)了RSA和HMAC兩種算法,還沒看過的同學(xué),建議先看上文。所以對于 基于JWT的Token用戶身份認證機制 來說,剩下的就是與接口結(jié)

    2023年04月16日
    瀏覽(18)
  • 【深入淺出 Spring Security(十三)】使用 JWT 進行前后端分離認證(附源碼)

    【深入淺出 Spring Security(十三)】使用 JWT 進行前后端分離認證(附源碼)

    JWT 全稱 Java web Token,在此所講述的是 JWT 用于身份認證,用服務(wù)器端生成的JWT去替代原始的Session認證,以提高安全性。 JWT本質(zhì)是一個Token令牌,是由三部分組成的字符串,分別是頭部(header)、載荷(payload)和簽名(signature)。頭部一般包含該 JWT 的基本信息,例如所使用的

    2024年02月12日
    瀏覽(25)
  • Spring Boot 優(yōu)雅集成 Spring Security 5.7(安全框架)與 JWT(雙令牌機制)

    Spring Boot 優(yōu)雅集成 Spring Security 5.7(安全框架)與 JWT(雙令牌機制)

    本章節(jié)將介紹 Spring Boot 集成 Spring Security 5.7(安全框架)。 ?? Spring Boot 2.x 實踐案例(代碼倉庫) Spring Security 是一個能夠為基于 Spring 的企業(yè)應(yīng)用系統(tǒng)提供聲明式的安全訪問控制解決方案的安全框架。 它提供了一組可以在 Spring 應(yīng)用上下文中配置的 Bean,充分利用了 Spring

    2024年02月12日
    瀏覽(53)
  • Springboot +spring security,自定義認證和授權(quán)異常處理器

    在Spring Security中異常分為兩種: AuthenticationException 認證異常 AccessDeniedException 權(quán)限異常 我們先給大家演示下如何自定義異常處理器,然后再結(jié)合源碼幫助大家進行分析 如何創(chuàng)建一個SpringSecurity項目,前面文章已經(jīng)有說明了,這里就不重復(fù)寫了。 3.1配置SecurityConfig 這里主要是

    2024年02月07日
    瀏覽(19)
  • SSM項目集成Spring Security 4.X版本(使用spring-security.xml 配置文件方式)

    SSM項目集成Spring Security 4.X版本(使用spring-security.xml 配置文件方式)

    目錄 前言 實戰(zhàn)開發(fā): 一、Spring Security整合到SSM項目 1. pom文件引入包 2. web.xml 配置 3. 添加 spring-security.xml 文件 二、Spring Security實戰(zhàn)應(yīng)用 1. 項目結(jié)構(gòu) 2. pom文件引入 3. web.xml 配置 4. Spring?配置?applicationContext.xml 5.?spring-security.xml 配置 6.?springmvc.xml?配置 7. 創(chuàng)建實體類 8. DAO層實

    2024年01月24日
    瀏覽(22)
  • Java21 + SpringBoot3使用Spring Security時如何在子線程中獲取到認證信息

    Java21 + SpringBoot3使用Spring Security時如何在子線程中獲取到認證信息

    目錄 前言 原因分析 解決方案 方案1:手動設(shè)置線程中的認證信息 方案2:使用 DelegatingSecurityContextRunnable 創(chuàng)建線程 方案3:修改 Spring Security 安全策略 通過設(shè)置JVM參數(shù)修改安全策略 通過 SecurityContextHolder 修改安全策略 總結(jié) 近日心血來潮想做一個開源項目,目標是做一款可以適

    2024年02月19日
    瀏覽(21)
  • 【重磅】:Spring Initializer 已經(jīng)不支持Java8,也就是SpringBoot2.x項目初始化

    【重磅】:Spring Initializer 已經(jīng)不支持Java8,也就是SpringBoot2.x項目初始化

    我們可以看到在IDEA內(nèi)置的Spring Initializer中 Java版本選擇模塊已經(jīng)不支持1.8了,同樣的,官網(wǎng)也不再支持了 Spring Boot 3.x要求 Java最低版本為17, 最新的SpringBoot版本已經(jīng)要求Java21了 所以,你可以升級Java版本,使用SpringBoot3.X 我們可以嘗試查看一下, 訪問Spring官網(wǎng),按照下圖操作

    2024年02月04日
    瀏覽(26)
  • SpringCloud Gateway + Security + JWT 最快速的集成

    Springboot版本采用的是最新的: 網(wǎng)關(guān)主要采用的是:

    2024年02月16日
    瀏覽(17)
  • Spring Security Oauth2.1 最新版 1.1.0 整合 gateway 完成授權(quán)認證(擁抱 springboot 3.1)

    Spring Security Oauth2.1 最新版 1.1.0 整合 gateway 完成授權(quán)認證(擁抱 springboot 3.1)

    目錄 背景 demo地址 版本 Spring Boot 3.1 Spring Authorization Server 1.1.0 基礎(chǔ) spring security OAuth2 模塊構(gòu)成 授權(quán)方式 認證方式 集成過程 官方demo 代碼集成 依賴 授權(quán)服務(wù)AuthorizationServerConfig配置 重要組件 測試 查看授權(quán)服務(wù)配置 訪問授權(quán)服務(wù) 授權(quán) 回調(diào) 獲取?access_token 獲取用戶信息 個性

    2024年02月08日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包