手把手教你用Java实现一套简单的鉴权服务
背景
鉴权服务可以帮助应用程序确认一个请求是否合法,从而保障应用程序的安全性。本攻略将介绍如何使用Java实现一个简单的鉴权服务。
步骤
1. 设计API
首先需要设计出鉴权服务的API。通常情况下,鉴权服务的API应该包括以下几个接口:
login(username, password)
:用于用户登录,其中username表示用户名,password表示密码,如果登录成功,则返回一个token,否则返回错误信息;auth(token)
:用于验证一个token是否合法,如果合法,则返回用户信息,否则返回错误信息;
以下是一个简单的API设计示例:
POST /api/auth/login HTTP/1.1
Content-Type: application/json
{
"username": "foo",
"password": "bar"
}
HTTP/1.1 200 OK
Content-Type: application/json
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF...qXA",
"expires_in": 3600
}
POST /api/auth HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF...qXA
HTTP/1.1 200 OK
Content-Type: application/json
{
"username": "foo",
"roles": ["admin", "user"]
}
其中,/api/auth/login
用于登录,/api/auth
用于验证token。返回的token包括一个JWT的字符串和token的过期时间(expires_in
)。
2. 实现鉴权服务
接下来需要实现一个鉴权服务,可以使用Spring Boot框架来快速实现。具体实现过程可以参考Spring Boot官方文档。
以下是一个简单的实现示例:
@Service
public class JWTAuthService {
private final String SECRET_KEY = "my_secret_key"; // 密钥
private final long EXPIRATION_TIME = 3600; // token过期时间,单位为秒
// 登录方法
public String login(String username, String password) {
if (!isValidUser(username, password)) {
throw new RuntimeException("Invalid credentials");
}
return createToken(username, getRoles(username));
}
// 验证token方法
public Map<String, Object> auth(String token) {
if (!isValidToken(token)) {
throw new RuntimeException("Invalid token");
}
Claims claims = Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
Map<String, Object> result = new HashMap<>();
result.put("username", claims.getSubject());
result.put("roles", claims.get("roles"));
return result;
}
// 创建token方法
private String createToken(String username, List<String> roles) {
Date now = new Date();
Date expiration = new Date(now.getTime() + EXPIRATION_TIME);
JwtBuilder builder = Jwts.builder()
.setSubject(username)
.claim("roles", roles)
.setIssuedAt(now)
.setExpiration(expiration)
.signWith(SignatureAlgorithm.HS256, SECRET_KEY);
return builder.compact();
}
// 验证用户方法
private boolean isValidUser(String username, String password) {
// TODO: 实现验证逻辑
return true;
}
// 获取用户角色方法
private List<String> getRoles(String username) {
// TODO: 实现获取角色逻辑
return List.of("admin", "user");
}
// 验证token方法
private boolean isValidToken(String token) {
try {
Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
return true;
} catch (SignatureException e) {
// token无效
} catch (ExpiredJwtException e) {
// token过期
} catch (Exception e) {
// 其他异常
}
return false;
}
}
在上面的代码中,createToken
方法用于创建token,isValidUser
和getRoles
方法分别用于验证用户和获取角色,isValidToken
方法用于验证token是否合法。
3. 编写测试用例
最后需要编写测试用例,确保鉴权服务的功能正确。
以下是一个简单的测试用例示例:
@SpringBootTest
class JWTAuthServiceTests {
@Autowired
private JWTAuthService authService;
@Test
void testLoginSuccess() {
String token = authService.login("foo", "bar");
assertNotEquals("", token);
}
@Test
void testLoginFailure() {
Assertions.assertThrows(RuntimeException.class, () -> {
authService.login("foo", "wrong_password");
});
}
@Test
void testAuthSuccess() {
String token = authService.login("foo", "bar");
Map<String, Object> result = authService.auth(token);
assertEquals("foo", result.get("username"));
assertTrue(((List<String>) result.get("roles")).contains("admin"));
}
@Test
void testInvalidToken() {
Assertions.assertThrows(RuntimeException.class, () -> {
authService.auth("");
});
}
}
在上面的测试用例中,testLoginSuccess
用于测试登录成功情况,testLoginFailure
用于测试登录失败情况,testAuthSuccess
用于测试验证token方法,testInvalidToken
用于测试无效的token情况。
示例说明
以下是两个示例说明:
示例1:Spring Security
Spring Security是一个流行的安全框架,可以帮助开发者快速实现各种安全功能,包括鉴权、授权、认证等。Spring Security基于filter chain实现,可以轻易地加入到Spring Boot项目中。
在使用Spring Security时,可以使用JwtAuthenticationTokenFilter
这个filter来实现鉴权服务。具体实现方式可以参考Spring Security官方文档。
示例2:Spring Cloud Gateway
Spring Cloud Gateway是一种基于Spring Boot的API网关,可以帮助开发者实现路由、转发、过滤等功能。在实现API网关时,通常需要加上鉴权功能,以确保网关能够正确地转发请求。
使用Spring Cloud Gateway时,可以使用SpringCloudGatewayConfigurerAdapter
这个adapter来实现鉴权服务。具体实现方式可以参考Spring Cloud Gateway官方文档。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:手把手教你用Java实现一套简单的鉴权服务 - Python技术站