Java 基础教程

Java 面向对象

Java 高级教程

Java 笔记

Java FAQ

java jwt单点登录


在 Java 中实现 JWT(JSON Web Token)单点登录有多种方式,以下是其中一些常见的实现方式以及它们的步骤流程、依赖坐标和示例代码。

方式一:使用 Spring Security 和 jjwt 库

依赖坐标:

在你的项目的 Maven 或 Gradle 配置文件中添加以下依赖:

Maven:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.2</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>

Gradle:

implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'io.jsonwebtoken:jjwt-api:0.11.2'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.2'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.2'

步骤流程:

  • 配置 Spring Security: 在 Spring Boot 项目中,你需要配置 Spring Security 来处理认证和授权。创建一个继承自 WebSecurityConfigurerAdapter 的配置类,然后配置安全规则。
  • 生成和验证 JWT: 使用 jjwt 库创建和验证 JWT。你可以创建一个 JWT 工具类来处理生成和验证 JWT。
  • 单点登录逻辑: 当用户成功登录后,生成一个 JWT 并返回给客户端。客户端在后续的请求中携带 JWT。服务器接收到请求后,通过解析 JWT 并验证其有效性来判断用户是否已登录。

示例代码:

Spring Security 配置:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/public/**").permitAll()  // 允许公共访问的路径
            .anyRequest().authenticated()          // 其他请求需要认证
            .and()
            .formLogin()
            .and()
            .logout()
            .and()
            .csrf().disable();
    }
}

JWT 工具类:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JwtUtil {
    private static final String SECRET_KEY = "yourSecretKey";
    private static final long EXPIRATION_TIME = 86400000; // 1 day in milliseconds

    public static String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        return Jwts.builder()
            .setClaims(claims)
            .setSubject(userDetails.getUsername())
            .setIssuedAt(new Date(System.currentTimeMillis()))
            .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
            .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
            .compact();
    }

    public static boolean validateToken(String token, UserDetails userDetails) {
        String username = extractUsername(token);
        return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
    }

    private static String extractUsername(String token) {
        return extractClaims(token).getSubject();
    }

    private static boolean isTokenExpired(String token) {
        Date expiration = extractClaims(token).getExpiration();
        return expiration.before(new Date());
    }

    private static Claims extractClaims(String token) {
        return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
    }
}

这只是一个简单的示例,实际项目中还需要考虑异常处理、密码加密等方面的细节。

方式二:使用 Spring Boot 和 Spring Security OAuth2

依赖坐标:

在你的项目的 Maven 或 Gradle 配置文件中添加以下依赖:

Maven:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

Gradle:

implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'

步骤流程:

  • 配置 OAuth2 客户端: 在 Spring Boot 项目中,配置 OAuth2 客户端信息,包括提供商(如 Google、GitHub、Okta 等)的认证信息。
  • 处理登录回调: 配置回调 URL 并处理 OAuth2 提供商的授权回调,获取用户信息并生成 JWT。
  • 生成和验证 JWT: 生成和验证 JWT 的逻辑与方式一中的示例类似。

示例代码:

OAuth2 配置:

@Configuration
@EnableOAuth2Client
public class OAuth2Config {

    @Bean
    public OAuth2AuthorizedClientService authorizedClientService() {
        return new InMemoryOAuth2AuthorizedClientService();
    }

    @Bean
    public ClientRegistrationRepository clientRegistrationRepository() {
        return new InMemoryClientRegistrationRepository(
            ClientRegistration.withRegistrationId("google")
                .clientId("yourClientId")
                .clientSecret("yourClientSecret")
                .redirectUriTemplate("{baseUrl}/login/oauth2/code/{registrationId}")
                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                .userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo")
                .userNameAttributeName(IdTokenClaimNames.SUB)
                .clientName("Google")
                .build()
        );
    }
}

登录回调处理:

@Controller
public class OAuth2LoginController {

    @GetMapping("/login/oauth2/code/google")
    public String handleGoogleLogin(@AuthenticationPrincipal OAuth2User oauth2User) {
        // 获取用户信息并生成 JWT
        UserDetails userDetails = mapOAuth2UserToUserDetails(oauth2User);
        String token = JwtUtil.generateToken(userDetails);
        // 在此处可以根据业务逻辑重定向到主页或其他页面,并将 JWT 传递给客户端
        return "redirect:/";
    }

    private UserDetails mapOAuth2UserToUserDetails(OAuth2User oauth2User) {
        // 将 OAuth2User 转换为 UserDetails,你可能需要根据实际情况进行调整
        // 返回 UserDetails 对象,用于生成 JWT
    }
}

请注意,以上示例代码仅为概念性示例,实际项目中需要根据具体的业务需求进行适当的调整和扩展。

这些方式只是 JWT 单点登录的一部分实现方式,实际上还有其他库和框架可以用于实现类似的功能。选择合适的方式取决于你的项目需求、技术栈和团队经验。在实际开发中,还需考虑安全性、性能、异常处理等方面的细节。

JWT是一种用于安全传输信息的开放标准,通常由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。###方 ...
在Java中刷新JWT(JSONWebToken)令牌,可以使用不同的实现方式。令牌刷新请求:在令牌即将过期时,客户端发送一个令牌刷新请求, ...
如果您还没有安装Django,可以使用pip进行安装:现在,让我们创建一个新的Django项目和应用,然后添加登录功能。py`文件,并添加以 ...
MongoDB 如何通过 Shell 命令登录连接服务器,主要有两种形式,一是相关登录信息通过字符串包在一起,另一种是通过各自登录选项指定。 ...
在Django中实现选择角色登录的功能,可以通过使用Django自带的User模型和自定义用户模型来实现。py&quot;文件中定义管理员用 ...