欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot整合SpringSecurity和JWT和Redis實(shí)現(xiàn)統(tǒng)一鑒權(quán)認(rèn)證

 更新時(shí)間:2023年11月06日 09:37:49   作者:放風(fēng)講故事  
Spring Security是一個(gè)可以為Java應(yīng)用程序提供全面安全服務(wù)的框架,同時(shí)它也可以輕松擴(kuò)展以滿足自定義需求,本文主要介紹了SpringBoot整合SpringSecurity和JWT和Redis實(shí)現(xiàn)統(tǒng)一鑒權(quán)認(rèn)證,感興趣的可以了解一下

一、介紹

Spring Security是一個(gè)強(qiáng)大且高度可定制的身份驗(yàn)證和訪問(wèn)控制框架。它是保護(hù)基于Spring的應(yīng)用程序的實(shí)際標(biāo)準(zhǔn)。Spring Security是一個(gè)可以為Java應(yīng)用程序提供全面安全服務(wù)的框架。同時(shí),它也可以輕松擴(kuò)展以滿足自定義需求。

二、主要功能

Authentication (認(rèn)證),就是用戶登錄
Authorization (授權(quán)):一旦身份驗(yàn)證成功,判斷用戶擁有什么權(quán)限,可以訪問(wèn)什么資源
防止跨站請(qǐng)求偽造(CSRF):Spring Security提供了內(nèi)置的防護(hù)機(jī)制,可以防止跨站請(qǐng)求偽造攻擊。
密碼存儲(chǔ):Spring Security提供了多種密碼存儲(chǔ)格式,包括明文、加密和哈希。
集成其他安全框架:Spring Security可以與其他安全框架如OAuth2、JWT等進(jìn)行集成,以提供更全面的安全解決方案。

三、原理

? SpringSecurity的原理其實(shí)就是一個(gè)過(guò)濾器鏈,內(nèi)部包含了提供各種功能的過(guò)濾器。

1. SpringSecurity 過(guò)濾器鏈

在這里插入圖片描述

SpringSecurity 采用的是責(zé)任鏈的設(shè)計(jì)模式,它有一條很長(zhǎng)的過(guò)濾器鏈。

  • SecurityContextPersistenceFilter:每次請(qǐng)求處理之前將該請(qǐng)求相關(guān)的安全上下文信息加載到 SecurityContextHolder 中。
  • LogoutFilter:用于處理退出登錄。
  • UsernamePasswordAuthenticationFilter:用于處理基于表單的登錄請(qǐng)求,從表單中獲取用戶名和密碼。
  • BasicAuthenticationFilter:檢測(cè)和處理 http basic 認(rèn)證。
  • ExceptionTranslationFilter:處理過(guò)濾器鏈中拋出的任何AccessDeniedException和AuthenticationException 。
  • FilterSecurityInterceptor:負(fù)責(zé)權(quán)限校驗(yàn)的過(guò)濾器,可以看做過(guò)濾器鏈的出口。

流程說(shuō)明:客戶端發(fā)起一個(gè)請(qǐng)求,進(jìn)入 Security 過(guò)濾器鏈。
1.當(dāng)?shù)?LogoutFilter 的時(shí)候判斷是否是登出路徑,如果是登出路徑則到 logoutHandler ,如果登出成功則到logoutSuccessHandler 登出成功處理,如果登出失敗則由 ExceptionTranslationFilter ;如果不是登出路徑則直接進(jìn)入下一個(gè)過(guò)濾器。

2.當(dāng)?shù)?UsernamePasswordAuthenticationFilter 的時(shí)候判斷是否為登錄路徑,如果是,則進(jìn)入該過(guò)濾器進(jìn)行登錄操作,如果登錄失敗則到 AuthenticationFailureHandler 登錄失敗處理器處理,如果登錄成功則到 AuthenticationSuccessHandler 登錄成功處理器處理,如果不是登錄請(qǐng)求則不進(jìn)入該過(guò)濾器。

3.當(dāng)?shù)?FilterSecurityInterceptor 的時(shí)候會(huì)拿到 uri ,根據(jù) uri 去找對(duì)應(yīng)的鑒權(quán)管理器,鑒權(quán)管理器做鑒權(quán)工作,鑒權(quán)成功則到 Controller 層否則到 AccessDeniedHandler 鑒權(quán)失敗處理器處理。

2. JWT校驗(yàn)登錄的校驗(yàn)流程

在這里插入圖片描述

首先前端一樣是把登錄信息發(fā)送給后端,后端查詢數(shù)據(jù)庫(kù)校驗(yàn)用戶的賬號(hào)和密碼是否正確,正確的話則使用jwt生成token,并且返回給前端。以后前端每次請(qǐng)求時(shí),都需要攜帶token,后端獲取token后,使用jwt進(jìn)行驗(yàn)證用戶的token是否無(wú)效或過(guò)期,驗(yàn)證成功后才去做相應(yīng)的邏輯。

四、Spring Boot整合Redis、SpringSecurity、JWT的示例demo

  • 添加依賴項(xiàng)在 pom.xml 文件中添加以下依賴項(xiàng):
   <dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</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>
</dependencies>`
  • 創(chuàng)建Redis配置類
@Configuration
public class RedisConfig {

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Bean
    public JedisConnectionFactory jedisConnectionFactory() {
        return new JedisConnectionFactory(new RedisStandaloneConfiguration(host, port));
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        final RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(jedisConnectionFactory());
        return template;
    }
}
  • 創(chuàng)建 JwtTokenUtil 類,用于生成和驗(yàn)證JWT令牌。
@Component
public class JwtTokenUtil implements Serializable {

    private static final long serialVersionUID = -2550185165626007488L;

    private static final String secret = "mySecret";

    public String getUsernameFromToken(String token) {
        return getClaimFromToken(token, Claims::getSubject);
    }

    public Date getExpirationDateFromToken(String token) {
        return getClaimFromToken(token, Claims::getExpiration);
    }

    public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = getAllClaimsFromToken(token);
        return claimsResolver.apply(claims);
    }

    private Claims getAllClaimsFromToken(String token) {
        return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
    }

    private Boolean isTokenExpired(String token) {
        final Date expiration = getExpirationDateFromToken(token);
        return expiration.before(new Date());
    }

    public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        return doGenerateToken(claims, userDetails.getUsername());
    }

    private String doGenerateToken(Map<String, Object> claims, String subject) {
        return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + 5 * 60 * 60 * 1000))
                .signWith(SignatureAlgorithm.HS512, secret).compact();
    }

    public Boolean validateToken(String token, UserDetails userDetails) {
        final String username = getUsernameFromToken(token);
        return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
    }
}` 
  • 創(chuàng)建 JwtAuthenticationEntryPoint 類,用于處理未經(jīng)授權(quán)的請(qǐng)求。
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable {

    private static final long serialVersionUID = -7858869558953243875L;

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
                         AuthenticationException authException) throws IOException {

        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
    }
}` 
  • 創(chuàng)建 JwtRequestFilter 類,用于解析和驗(yàn)證JWT令牌。
@Component
public class JwtRequestFilter extends OncePerRequestFilter {

    @Autowired
    private MyUserDetailsService myUserDetailsService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {

        final String requestTokenHeader = request.getHeader("Authorization");

        String username = null;
        String jwtToken = null;

        if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
            jwtToken = requestTokenHeader.substring(7);
            try {
                username = jwtTokenUtil.getUsernameFromToken(jwtToken);
            } catch (IllegalArgumentException e) {
                System.out.println("Unable to get JWT Token");
            } catch (ExpiredJwtException e) {
                System.out.println("JWT Token has expired");
            }
        } else {
            logger.warn("JWT Token does not begin with Bearer String");
        }

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {

            UserDetails userDetails = this.myUserDetailsService.loadUserByUsername(username);

            if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {

                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                usernamePasswordAuthenticationToken
                        .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        }
        chain.doFilter(request, response);
    }
}` 
  • 配置Spring Security
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;

    @Autowired
    private UserDetailsService jwtUserDetailsService;

    @Autowired
    private JwtRequestFilter jwtRequestFilter;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(jwtUserDetailsService).passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.csrf().disable()
                .authorizeRequests().antMatchers("/authenticate").permitAll().
                        anyRequest().authenticated().and().
                        exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }
}`

以上是簡(jiǎn)單的Spring Boot整合Redis、Security、JWT和Redis的示例,可以根據(jù)自己的實(shí)際需求進(jìn)行調(diào)整。更多相關(guān)SpringBoot 統(tǒng)一鑒權(quán)認(rèn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java.io.EOFException產(chǎn)生原因及解決方法(附代碼)

    java.io.EOFException產(chǎn)生原因及解決方法(附代碼)

    java.io.EOFException表示在讀取數(shù)據(jù)時(shí)突然遇到了文件或流的末尾,也就是說(shuō)客戶端或服務(wù)器已經(jīng)關(guān)閉了連接,但是你還在嘗試讀取數(shù)據(jù),這篇文章主要給大家介紹了關(guān)于java.io.EOFException產(chǎn)生原因及解決的相關(guān)資料,需要的朋友可以參考下
    2023-09-09
  • Java連接超時(shí)的幾種情況以及讀取代碼

    Java連接超時(shí)的幾種情況以及讀取代碼

    在Java編程中連接超時(shí)異常是指在建立網(wǎng)絡(luò)連接時(shí),無(wú)法在給定的時(shí)間內(nèi)成功建立連接的異常,這篇文章主要給大家介紹了關(guān)于Java連接超時(shí)的幾種情況以及讀取的相關(guān)資料,需要的朋友可以參考下
    2024-02-02
  • Java利用POI讀寫(xiě)Excel文件工具類

    Java利用POI讀寫(xiě)Excel文件工具類

    這篇文章主要為大家詳細(xì)介紹了Java利用POI讀寫(xiě)Excel文件的工具類,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • SpringBoot處理JSON數(shù)據(jù)方法詳解

    SpringBoot處理JSON數(shù)據(jù)方法詳解

    這篇文章主要介紹了SpringBoot整合Web開(kāi)發(fā)中Json數(shù)據(jù)處理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-10-10
  • Java 照片對(duì)比功能的實(shí)現(xiàn)

    Java 照片對(duì)比功能的實(shí)現(xiàn)

    這篇文章主要介紹了Java 照片比對(duì)功能實(shí)現(xiàn)類的示例代碼,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下
    2020-12-12
  • mybatis如何根據(jù)表逆向自動(dòng)化生成代碼實(shí)例

    mybatis如何根據(jù)表逆向自動(dòng)化生成代碼實(shí)例

    逆向工程是一個(gè)專門(mén)為 MyBatis 框架使用者設(shè)計(jì)的代碼生成器,可以根據(jù)數(shù)據(jù)庫(kù)中的表字段名,自動(dòng)生成 POJO 類,mapper 接口與 SQL 映射文件,這篇文章主要給大家介紹了關(guān)于mybatis如何根據(jù)表逆向自動(dòng)化生成代碼的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • Springboot教程之如何設(shè)置springboot熱重啟

    Springboot教程之如何設(shè)置springboot熱重啟

    這篇文章主要介紹了Springboot教程之如何設(shè)置springboot熱重啟,本文通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • 關(guān)于ReentrantLock原理全面解讀

    關(guān)于ReentrantLock原理全面解讀

    這篇文章主要介紹了關(guān)于ReentrantLock原理全面解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • 使用Mybatis-plus實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)表的內(nèi)部字段進(jìn)行比較

    使用Mybatis-plus實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)表的內(nèi)部字段進(jìn)行比較

    這篇文章主要介紹了使用Mybatis-plus實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)表的內(nèi)部字段進(jìn)行比較方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Java 基礎(chǔ)詳解(泛型、集合、IO、反射)

    Java 基礎(chǔ)詳解(泛型、集合、IO、反射)

    下面小編就為大家?guī)?lái)一篇Java 基礎(chǔ)詳解(泛型、集合、IO、反射)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10

最新評(píng)論