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

SpringBoot整合SpringSecurity和JWT和Redis實現(xiàn)統(tǒng)一鑒權認證

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

一、介紹

Spring Security是一個強大且高度可定制的身份驗證和訪問控制框架。它是保護基于Spring的應用程序的實際標準。Spring Security是一個可以為Java應用程序提供全面安全服務的框架。同時,它也可以輕松擴展以滿足自定義需求。

二、主要功能

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

三、原理

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

1. SpringSecurity 過濾器鏈

在這里插入圖片描述

SpringSecurity 采用的是責任鏈的設計模式,它有一條很長的過濾器鏈。

  • SecurityContextPersistenceFilter:每次請求處理之前將該請求相關的安全上下文信息加載到 SecurityContextHolder 中。
  • LogoutFilter:用于處理退出登錄。
  • UsernamePasswordAuthenticationFilter:用于處理基于表單的登錄請求,從表單中獲取用戶名和密碼。
  • BasicAuthenticationFilter:檢測和處理 http basic 認證。
  • ExceptionTranslationFilter:處理過濾器鏈中拋出的任何AccessDeniedException和AuthenticationException 。
  • FilterSecurityInterceptor:負責權限校驗的過濾器,可以看做過濾器鏈的出口。

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

2.當?shù)?UsernamePasswordAuthenticationFilter 的時候判斷是否為登錄路徑,如果是,則進入該過濾器進行登錄操作,如果登錄失敗則到 AuthenticationFailureHandler 登錄失敗處理器處理,如果登錄成功則到 AuthenticationSuccessHandler 登錄成功處理器處理,如果不是登錄請求則不進入該過濾器。

3.當?shù)?FilterSecurityInterceptor 的時候會拿到 uri ,根據(jù) uri 去找對應的鑒權管理器,鑒權管理器做鑒權工作,鑒權成功則到 Controller 層否則到 AccessDeniedHandler 鑒權失敗處理器處理。

2. JWT校驗登錄的校驗流程

在這里插入圖片描述

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

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

  • 添加依賴項在 pom.xml 文件中添加以下依賴項:
   <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 類,用于生成和驗證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)授權的請求。
@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 類,用于解析和驗證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);
    }
}`

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

相關文章

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

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

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

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

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

    Java利用POI讀寫Excel文件工具類

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

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

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

    Java 照片對比功能的實現(xiàn)

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

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

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

    Springboot教程之如何設置springboot熱重啟

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

    關于ReentrantLock原理全面解讀

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

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

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

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

    下面小編就為大家?guī)硪黄狫ava 基礎詳解(泛型、集合、IO、反射)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10

最新評論