统一身份认证系统
小明:嘿,小李,我最近在做一个演示系统,想加个统一身份认证的功能,你有经验吗?
小李:哦,统一身份认证啊,这在现代系统中确实很重要。你是用什么技术栈呢?

小明:我是用Java Web做的,Spring Boot框架。我想让用户登录后才能访问某些页面,比如演示内容。
小李:那你可以考虑使用Spring Security或者Shiro来实现。不过,如果要更灵活一点,可以自己写一个简单的认证模块。
小明:听起来不错,但我不太清楚具体怎么操作。你能给我讲讲吗?
小李:当然可以。我们可以从用户登录开始,先创建一个登录表单,然后验证用户名和密码。假设我们有一个数据库,里面存储了用户信息。
小明:对,数据库里有用户表,里面有username和password字段。
小李:那我们可以先写一个登录接口,接收用户名和密码,然后查询数据库看看是否有匹配的用户。如果有,就生成一个session或者token,表示用户已经登录。
小明:那这个token怎么处理呢?是不是每次请求都要携带它?
小李:是的。通常我们会使用JWT(JSON Web Token)来实现无状态的认证。这样就不需要在服务器上维护session了,适合分布式系统。
小明:明白了,那我可以先写一个登录的API,返回一个JWT token,然后在后续请求中带上这个token。
小李:没错。接下来,我们需要在每个需要权限的接口上添加拦截器,检查请求头中的token是否有效。如果无效,就返回401错误。
小明:那具体怎么实现呢?有没有代码示例?
小李:有的,我可以给你一个简单的例子。首先,我们创建一个User实体类,包含username和password属性。
小明:好的,那User.java应该是这样的:
public class User {
private String username;
private String password;
// 构造方法、getter和setter
}

小李:接着,我们创建一个LoginController,用来处理登录请求。
小明:那LoginController.java应该包含哪些内容?
小李:大致如下:
@RestController
@RequestMapping("/api/auth")
public class LoginController {
@Autowired
private UserService userService;
@PostMapping("/login")
public ResponseEntity> login(@RequestBody LoginRequest request) {
User user = userService.findByUsername(request.getUsername());
if (user == null || !user.getPassword().equals(request.getPassword())) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");
}
String token = JWT.create()
.withSubject(user.getUsername())
.withExpiresAt(new Date(System.currentTimeMillis() + 3600000)) // 1小时有效期
.sign(Algorithm.HMAC256("secret-key"));
return ResponseEntity.ok().body(Map.of("token", token));
}
}
小明:这个看起来很清晰。那Token是怎么被验证的呢?
小李:我们可以通过一个拦截器来验证Token。例如,在Spring Boot中,可以创建一个Filter或者使用Spring Security的过滤链。
小明:那能不能直接用Spring Security来实现?
小李:当然可以。不过如果你只是想做一个简单的演示系统,自己实现一个拦截器会更轻量。
小明:那我应该怎么写这个拦截器呢?
小李:可以写一个Filter,拦截所有请求,检查Header中的Authorization字段,然后解析JWT。
小明:好的,那代码大概是这样的:
@Component
public class JwtFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
String token = req.getHeader("Authorization");
if (token != null && token.startsWith("Bearer ")) {
token = token.substring(7);
try {
DecodedJWT decodedJWT = JWT.decode(token);
String username = decodedJWT.getSubject();
// 这里可以进一步验证用户是否存在,或者根据token做其他处理
// 为了简单起见,这里不验证用户存在性
} catch (JWTVerificationException e) {
((HttpServletResponse) response).sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid token");
return;
}
} else {
((HttpServletResponse) response).sendError(HttpServletResponse.SC_UNAUTHORIZED, "Missing token");
return;
}
chain.doFilter(request, response);
}
}
小明:这个拦截器看起来没问题。那我要怎么把它加到Spring Boot应用中呢?
小李:可以在配置类中注册这个Filter。例如,创建一个WebConfig类,继承WebMvcConfigurer,然后添加过滤器。
小明:那WebConfig.java应该是什么样的?
小李:像这样:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private JwtFilter jwtFilter;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtFilter).addPathPatterns("/api/**");
}
}
小明:嗯,这样就能对所有/api下的路径进行拦截了。
小李:对,这样用户访问这些接口时,必须带上有效的token,否则会被拒绝。
小明:那这样的话,我的演示系统就可以控制谁能看到哪些内容了。
小李:没错,这就是统一身份认证的作用。现在你有了一个基本的认证系统,可以继续扩展,比如加入角色管理、权限控制等。
小明:听起来很棒。那我现在可以开始开发了。不过,我还想知道,这种系统是否可以申请软件著作权?
小李:当然可以。只要你的系统具有独创性,并且符合相关法律要求,就可以申请软件著作权。
小明:那我需要准备哪些材料呢?
小李:通常需要提供软件的源代码、文档、用户手册,以及一些证明作品原创性的材料。你可以去中国版权保护中心官网了解详细流程。
小明:明白了。那我得先把代码整理好,再准备相关资料。
小李:是的,建议你尽早申请,以免被他人抢先。
小明:谢谢你,小李!这次交流让我对统一身份认证和演示系统的开发有了更深的理解。
小李:不客气,希望你能顺利开发出自己的系统,并成功申请软件著作权!