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

單點(diǎn)登錄的概念及SpringBoot實(shí)現(xiàn)單點(diǎn)登錄的操作方法

 更新時(shí)間:2024年10月26日 11:23:18   作者:這孩子叫逆  
在本文中,我們將使用Spring Boot構(gòu)建一個(gè)基本的單點(diǎn)登錄系統(tǒng),我們將介紹如何使用Spring Security和JSON Web Tokens(JWTs)來實(shí)現(xiàn)單點(diǎn)登錄功能,本文假設(shè)您已經(jīng)熟悉Spring Boot和Spring Security,感興趣的朋友一起看看吧

在現(xiàn)代的Web應(yīng)用程序中,單點(diǎn)登錄(Single Sign-On)已經(jīng)變得越來越流行,在本文中,我們將使用Spring Boot構(gòu)建一個(gè)基本的單點(diǎn)登錄系統(tǒng),需要的可以參考一下

前言

在現(xiàn)代的Web應(yīng)用程序中,單點(diǎn)登錄(Single Sign-On)已經(jīng)變得越來越流行。單點(diǎn)登錄使得用戶只需要一次認(rèn)證即可訪問多個(gè)應(yīng)用程序,同時(shí)也提高了應(yīng)用程序的安全性。Spring Boot作為一種廣泛使用的Web開發(fā)框架,在單點(diǎn)登錄方面也提供了很好的支持。

在本文中,我們將使用Spring Boot構(gòu)建一個(gè)基本的單點(diǎn)登錄系統(tǒng)。我們將介紹如何使用Spring Security和JSON Web Tokens(JWTs)來實(shí)現(xiàn)單點(diǎn)登錄功能。本文假設(shè)您已經(jīng)熟悉Spring Boot和Spring Security。

什么是JWT

在介紹實(shí)現(xiàn)單點(diǎn)登錄之前,讓我們先了解一下JWT。JWT是一種基于JSON格式的開放標(biāo)準(zhǔn)(RFC 7519),用于在不同的應(yīng)用程序之間安全地傳輸信息。它由三個(gè)部分組成:

  • 標(biāo)頭(Header):包含JWT的類型和使用的簽名算法。
  • 負(fù)載(Payload):包含實(shí)際的信息。
  • 簽名(Signature):使用私鑰生成的簽名,用于驗(yàn)證JWT的真實(shí)性。

JWT通常在身份驗(yàn)證過程中使用,以便在不需要存儲(chǔ)用戶信息的情況下驗(yàn)證用戶身份。由于JWT是基于標(biāo)準(zhǔn)化的JSON格式構(gòu)建的,因此在多種編程語言中都可以輕松地實(shí)現(xiàn)和解析。

實(shí)現(xiàn)單點(diǎn)登錄

下面我們來介紹如何使用JWT實(shí)現(xiàn)基本的單點(diǎn)登錄系統(tǒng)。這個(gè)系統(tǒng)由兩個(gè)應(yīng)用程序組成:認(rèn)證應(yīng)用程序和資源應(yīng)用程序。用戶在認(rèn)證應(yīng)用程序上進(jìn)行一次身份驗(yàn)證之后,就可以訪問資源應(yīng)用程序。

認(rèn)證應(yīng)用程序

我們首先需要構(gòu)建一個(gè)認(rèn)證應(yīng)用程序,用于認(rèn)證用戶信息并生成JWT。

添加依賴

首先,我們需要添加以下依賴:

<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>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  • spring-boot-starter-security:用于提供基本的安全性支持。
  • jjwt:JSON Web Token的Java實(shí)現(xiàn)。
  • spring-boot-starter-web:用于提供Web應(yīng)用程序支持。

配置Spring Security

接下來,我們需要配置Spring Security。我們將使用Spring Security的默認(rèn)配置,并添加一個(gè)自定義的UserDetailsService來從數(shù)據(jù)庫中加載用戶信息。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  @Autowired
  private UserDetailsService userDetailsService;
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .csrf().disable()
      .authorizeRequests()
        .antMatchers("/auth/**").permitAll()
        .anyRequest().authenticated()
      .and().formLogin()
        .loginPage("/auth/login")
        .successHandler(authenticationSuccessHandler())
        .failureHandler(authenticationFailureHandler())
        .permitAll()
      .and().logout()
        .logoutUrl("/auth/logout")
        .logoutSuccessUrl("/auth/login?logout")
        .invalidateHttpSession(true)
        .deleteCookies("JSESSIONID");
  }
  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
  }
  @Bean
  public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
  }
  @Bean
  public AuthenticationSuccessHandler authenticationSuccessHandler() {
    return new JWTAuthenticationSuccessHandler();
  }
  @Bean
  public AuthenticationFailureHandler authenticationFailureHandler() {
    return new JWTAuthenticationFailureHandler();
  }
}

在上述配置中,我們定義了一個(gè)路由表達(dá)式"/auth/**"允許匿名訪問,這意味著認(rèn)證應(yīng)用程序的登錄和注冊頁面可以被未經(jīng)身份驗(yàn)證的用戶訪問。我們還定義了自定義的AuthenticationSuccessHandler和AuthenticationFailureHandler,用于在用戶身份驗(yàn)證成功或失敗時(shí)生成JWT并將其返回給用戶。這些處理程序?qū)⒃谙乱徊街袑?shí)現(xiàn)。

實(shí)現(xiàn)自定義的AuthenticationSuccessHandler和AuthenticationFailureHandler

在上述配置中,我們使用了自定義的AuthenticationSuccessHandler和AuthenticationFailureHandler。讓我們來實(shí)現(xiàn)它們。

public class JWTAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
  private static final String JWT_SECRET = "secret";
  private static final long JWT_EXPIRATION_TIME = 864000000; // 10 days
  @Override
  public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
    Authentication authentication) throws IOException, ServletException {
    String username = authentication.getName();
    String token = Jwts.builder()
      .setSubject(username)
      .setExpiration(new Date(System.currentTimeMillis() + JWT_EXPIRATION_TIME))
      .signWith(SignatureAlgorithm.HS512, JWT_SECRET.getBytes())
      .compact();
    response.setHeader("Authorization", "Bearer " + token);
    response.getWriter().write("{\"token\":\"Bearer " + token + "\"}");
    response.setContentType("application/json");
  }
}

在上述代碼中,我們使用了JJWT庫來生成JWT。在onAuthenticationSuccess方法中,我們首先從Authentication對象獲取用戶名,然后使用用戶名創(chuàng)建JWT。我們設(shè)置JWT的有效期為10天,并使用HS512簽名算法對JWT進(jìn)行簽名,使用一個(gè)字符串作為密鑰。最后,我們將JWT作為Bearer令牌添加到響應(yīng)消息頭中,并封裝在JSON格式的響應(yīng)體中返回給客戶端。

public class JWTAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
  @Override
  public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
    AuthenticationException exception) throws IOException, ServletException {
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    response.getWriter().write("{\"error\":\"Bad credentials\"}");
    response.setContentType("application/json");
  }
}

在上述代碼中,我們將響應(yīng)代碼設(shè)置為401(未經(jīng)授權(quán)),并向響應(yīng)體中添加一個(gè)錯(cuò)誤消息,以通知客戶端身份驗(yàn)證失敗。

實(shí)現(xiàn)授權(quán)控制器

現(xiàn)在我們已經(jīng)創(chuàng)建了認(rèn)證應(yīng)用程序的基本安全性,讓我們來構(gòu)建資源應(yīng)用程序并實(shí)現(xiàn)授權(quán)控制器,以確保只有經(jīng)過身份驗(yàn)證的用戶才可以訪問受保護(hù)的資源。我們將使用JWT來驗(yàn)證用戶身份。

@RestController
public class ResourceController {
  private static final String JWT_SECRET = "secret";
  @GetMapping("/resource")
  public ResponseEntity<String> getResource(HttpServletRequest request) {
    String token = request.getHeader("Authorization").replace("Bearer ", "");
    if (isValidJWT(token)) {
      return ResponseEntity.ok("Protected resource");
    } else {
      return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
    }
  }
  private boolean isValidJWT(String jwt) {
    try {
      Jwts.parser().setSigningKey(JWT_SECRET.getBytes()).parseClaimsJws(jwt);
      return true;
    } catch (JwtException e) {
      return false;
    }
  }
}

在上述代碼中,我們使用了一個(gè)示例的受保護(hù)資源路徑"/resource",該路徑只允許經(jīng)過身份驗(yàn)證的用戶訪問。我們從請求頭中提取Bearer令牌,并使用isValidJWT方法驗(yàn)證令牌的真實(shí)性。如果JWT有效,則返回200響應(yīng)代碼和受保護(hù)的資源;否則返回401(未經(jīng)授權(quán))響應(yīng)代碼。

資源應(yīng)用程序

現(xiàn)在我們已經(jīng)創(chuàng)建了認(rèn)證應(yīng)用程序,讓我們來創(chuàng)建一個(gè)資源應(yīng)用程序,以便用戶可以在驗(yàn)證后訪問它。資源應(yīng)用程序?qū)Ⅱ?yàn)證用戶是否具有訪問受保護(hù)資源的權(quán)限。

配置Spring Security

我們首先需要配置Spring Security,以使資源應(yīng)用程序能夠驗(yàn)證JWT并授予用戶訪問權(quán)限。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .csrf().disable()
      .authorizeRequests()
      .antMatchers("/resource").authenticated()
      .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
      .and().addFilterBefore(new JWTAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class);
  }
}

在上述配置中,我們定義了一個(gè)路由表達(dá)式"/resource",只有經(jīng)過身份驗(yàn)證的用戶才能訪問。我們還將會(huì)話管理策略設(shè)置為STATELESS,以避免使用HTTP會(huì)話。

實(shí)現(xiàn)JWTAuthorizationFilter

接下來,我們需要實(shí)現(xiàn)JWTAuthorizationFilter,以驗(yàn)證來自客戶端的JWT并將其與用戶信息相關(guān)聯(lián)。這將允許我們檢查用戶是否具有訪問資源的權(quán)限。

public class JWTAuthorizationFilter extends OncePerRequestFilter {
  private static final String JWT_SECRET = "secret";
  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
    FilterChain filterChain) throws ServletException, IOException {
    String authorizationHeader = request.getHeader("Authorization");
    if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
      filterChain.doFilter(request, response);
      return;
    }
    String jwt = authorizationHeader.replace("Bearer ", "");
    try {
      Jws<Claims> claimsJws = Jwts.parser().setSigningKey(JWT_SECRET.getBytes()).parseClaimsJws(jwt);
      String username = claimsJws.getBody().getSubject();
      List<GrantedAuthority> authorities = new ArrayList<>();
      UserDetails userDetails = new User(username, "", authorities);
      UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
        userDetails, null, userDetails.getAuthorities());
      SecurityContextHolder.getContext().setAuthentication(authentication);
    } catch (JwtException e) {
      throw new ServletException("Invalid JWT");
    }
    filterChain.doFilter(request, response);
  }
}

在上述代碼中,我們查詢Authorization頭以查找Bearer令牌。如果令牌不存在或不正確,則請求將繼續(xù)傳遞。否則,我們使用JJWT庫驗(yàn)證JWT的真實(shí)性,并獲取用戶的用戶名。我們將用戶名創(chuàng)建為Spring Security的UserDetails對象并創(chuàng)建一個(gè)UsernamePasswordAuthenticationToken,用于將身份驗(yàn)證信息設(shè)置為當(dāng)前Spring Security上下文的一部分。完成后,請求將繼續(xù)傳遞并授權(quán)用戶訪問資源。

測試

現(xiàn)在我們已經(jīng)創(chuàng)建了認(rèn)證應(yīng)用程序和資源應(yīng)用程序,讓我們對它們進(jìn)行測試。首先,我們在認(rèn)證應(yīng)用程序上注冊并登錄,以獲取JWT令牌。然后,我們將使用該令牌訪問資源應(yīng)用程序的受保護(hù)資源,并驗(yàn)證我們是否可以成功訪問。

# Register and login to authentication application
$ curl -s -X POST -H "Content-Type: application/json" -d '{"username":"user","password":"password"}' http://localhost:8080/auth/signup
$ curl -s -X POST -H "Content-Type: application/json" -d '{"username":"user","password":"password"}' http://localhost:8080/auth/login

# Get JWT token
$ TOKEN=$(curl -si -X POST -H "Content-Type: application/json" -d '{"username":"user","password":"password"}' http://localhost:8080/auth/login | grep 'Authorization:' | awk '{print $2}')

# Access protected resource in resource application
$ curl -s -H "Authorization: Bearer $TOKEN" http://localhost:8090/resource
Protected resource

通過測試,我們可以看到我們成功地訪問了資源應(yīng)用程序的受保護(hù)資源,并返回了正確的響應(yīng)。

總結(jié)

在本文中,我們使用Spring Boot,Spring Security和JWT實(shí)現(xiàn)了一個(gè)基本的單點(diǎn)登錄系統(tǒng)。我們介紹了JWT的概念,并演示了如何使用它來驗(yàn)證用戶身份。我們還創(chuàng)建了一個(gè)認(rèn)證應(yīng)用程序和一個(gè)資源應(yīng)用程序,以演示如何在多個(gè)應(yīng)用程序之間共享用戶身份驗(yàn)證信息。您可以將此范例用作基礎(chǔ)模板,進(jìn)一步擴(kuò)展它以適應(yīng)自己的應(yīng)用程序需求。

到此這篇關(guān)于單點(diǎn)登錄的概念及SpringBoot實(shí)現(xiàn)單點(diǎn)登錄的操作方法的文章就介紹到這了,更多相關(guān)springboot單點(diǎn)登錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot整合接口管理工具Swagger

    SpringBoot整合接口管理工具Swagger

    ? Swagger是一系列 RESTful API的工具,通過Swagger可以獲得項(xiàng)目的?種交互式文檔,客戶端SDK的自動(dòng)生成等功能。本文通過代碼示例詳細(xì)介紹了SpringBoot整合接口管理工具Swagger,需要的朋友可以借鑒參考
    2023-04-04
  • Java下載安裝和環(huán)境變量配置圖文教程

    Java下載安裝和環(huán)境變量配置圖文教程

    這篇文章主要為大家詳細(xì)介紹了Java下載安裝和環(huán)境變量配置圖文教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • Maven添加Tomcat插件實(shí)現(xiàn)熱部署代碼實(shí)例

    Maven添加Tomcat插件實(shí)現(xiàn)熱部署代碼實(shí)例

    這篇文章主要介紹了Maven添加Tomcat插件實(shí)現(xiàn)熱部署代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • 解決zuulGateway網(wǎng)關(guān)添加路由異常熔斷問題

    解決zuulGateway網(wǎng)關(guān)添加路由異常熔斷問題

    這篇文章主要介紹了解決zuulGateway網(wǎng)關(guān)添加路由異常熔斷問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • spring如何加載配置多個(gè)配置文件

    spring如何加載配置多個(gè)配置文件

    這篇文章主要介紹了spring如何加載配置多個(gè)配置文件,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • 詳解Java設(shè)計(jì)模式之抽象工廠模式

    詳解Java設(shè)計(jì)模式之抽象工廠模式

    設(shè)計(jì)模式是軟件設(shè)計(jì)中的一種常見方法,通過定義一系列通用的解決方案,來解決常見的軟件設(shè)計(jì)問題,其中,抽象工廠模式是一種非常常見的設(shè)計(jì)模式,文中有詳細(xì)的代碼示例供大家參考,感興趣的同學(xué)可以借鑒閱讀
    2023-05-05
  • 詳解Java類庫的概念以及import的使用方法

    詳解Java類庫的概念以及import的使用方法

    這篇文章主要介紹了詳解Java類庫的概念以及import的使用方法,是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • Spring?Cloud?Alibaba使用Nacos作為注冊中心和配置中心

    Spring?Cloud?Alibaba使用Nacos作為注冊中心和配置中心

    這篇文章主要為大家介紹了Spring?Cloud?Alibaba使用Nacos作為注冊中心和配置中心的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 詳解Java的Struts框架以及相關(guān)的MVC設(shè)計(jì)理念

    詳解Java的Struts框架以及相關(guān)的MVC設(shè)計(jì)理念

    這篇文章主要介紹了詳解Java的Struts框架以及相關(guān)的MVC設(shè)計(jì)理念,Struts是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下
    2015-12-12
  • JAVA發(fā)送http get/post請求,調(diào)用http接口、方法詳解

    JAVA發(fā)送http get/post請求,調(diào)用http接口、方法詳解

    這篇文章主要介紹了Java發(fā)送http get/post請求調(diào)用接口/方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04

最新評論