在Java中實現JWT(JSON Web Token)單點登錄(SSO)涉及多個步驟,包括創建JWT、驗證JWT以及實現單點登錄的邏輯。以下是一個基本的實現示例:
首先,你需要在你的項目中添加JWT相關的依賴。如果你使用的是Maven,可以在pom.xml
中添加以下依賴:
<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>
你需要創建一個JWT來存儲用戶的認證信息。以下是一個簡單的示例:
import io.jsonwebtoken.*;
import java.util.Base64;
import java.util.Date;
public class JwtUtil {
private static final String SECRET_KEY = "yourSecretKey"; // 應該是一個復雜的字符串
private static final long EXPIRATION_TIME = 86400000; // 24小時
public static String createToken(String username) {
return Jwts.builder()
.setSubject(username)
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS512, SECRET_KEY)
.compact();
}
public static String getUsernameFromToken(String token) {
Claims claims = Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
return claims.getSubject();
}
public static boolean isTokenExpired(String token) {
Claims claims = Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
return claims.getExpiration().before(new Date());
}
}
以下是一個簡單的單點登錄邏輯示例:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class JwtSSOFilter {
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException {
String token = request.getHeader("Authorization");
if (token == null || !JwtUtil.isTokenValid(token)) {
response.sendRedirect("/login");
return;
}
String username = JwtUtil.getUsernameFromToken(token);
request.setAttribute("username", username);
chain.doFilter(request, response);
}
}
在你的Web應用中配置過濾器,以便在每個請求中檢查JWT。以下是一個簡單的示例:
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(urlPatterns = "/*")
public class JwtSSOFilterConfig implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
JwtSSOFilter.doFilter((HttpServletRequest) request, (HttpServletResponse) response, chain);
}
@Override
public void destroy() {
}
}
創建一個簡單的登錄頁面,用戶可以在此頁面輸入用戶名和密碼,然后服務器會生成一個JWT并返回給客戶端。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<form action="/login" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username"><br><br>
<label for="password">Password:</label>
<input type="password" id="password" name="password"><br><br>
<button type="submit">Login</button>
</form>
</body>
</html>
在服務器端處理登錄請求,生成JWT并返回給客戶端。
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
// 這里應該有一個驗證用戶名和密碼的邏輯
if ("admin".equals(username) && "password".equals(password)) {
String token = JwtUtil.createToken(username);
response.setHeader("Authorization", token);
response.sendRedirect("/home");
} else {
response.sendRedirect("/login?error=Invalid%20username%20or%20password");
}
}
}
創建一個主頁,用戶登錄后可以訪問此頁面。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home</title>
</head>
<body>
<h1>Welcome, <span th:text="${username}"></span>!</h1>
</body>
</html>
以上示例展示了如何在Java中使用JWT實現單點登錄的基本流程。實際應用中,你可能需要添加更多的安全措施,例如密碼加密、HTTPS支持、會話管理等。