在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支持、会话管理等。