Spring boot 使用restful风格的spring security login

本文档介绍了如何在Spring Boot项目中使用RESTful风格的Spring Security进行登录。首先从Spring官网获取带有security、session和redis的项目,然后配置Redis并实现自定义的登录验证方式,通过session管理token。接着,重写过滤器,将登录请求由表单改为JSON提交。再者,定制成功的和失败的处理方法,以RESTful方式返回结果。最后,解决跨域问题,确保前端可以通过RESTful接口进行跨域登录请求。
摘要由CSDN通过智能技术生成

第一步,获取基本springboot项目

spring官网获取security+session+redis依赖的springboot项目
安装配置redis,修改配置文件,启动项目,拿到登录密码,用户名为user.
根据官方文档,配置demo项目,理解spring security的机制

第二步,添加自己的登录验证方式

添加session策略,让权限验证从session里获取token,而不是默认的cookie
重写自己的UserDetails,实现org.springframework.security.core.userdetails.UserDetails接口
重写自己的UserService,实现org.springframework.security.core.userdetails.UserDetailsService
接口,重写loadUserByUsername方法,从数据库根据username获取UserDetails
在WebSecuirtyConfig里加入配置:

/**
* Configure order web security with authentication manager build
*/

好的,以下是一个简单的示例: 首先,创建一个 Spring Boot 项目,并添加以下依赖: ```xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.7.0</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.4.197</version> <scope>runtime</scope> </dependency> </dependencies> ``` 其中,`spring-boot-starter-web` 用于创建 web 项目,`spring-boot-starter-data-jpa` 用于访问数据库,`spring-boot-starter-security` 用于实现安全认证,`jjwt` 用于生成和验证 JWT Token,`h2` 用于创建内存数据库。 接下来,创建一个 User 实体类: ```java @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false, unique = true) private String username; @Column(nullable = false) private String password; @Transient private String confirmPassword; // getter 和 setter 省略 } ``` 该实体类包含 id、username 和 password 三个字段,其中 username 是唯一的,password 会在存储时进行加密处理,confirmPassword 字段在注册时用于确认密码,不会被存储。 接着,创建 UserRepository 接口: ```java @Repository public interface UserRepository extends JpaRepository<User, Long> { User findByUsername(String username); } ``` 该接口继承了 JpaRepository 接口,用于访问 User 实体类对应的表。其中,`findByUsername` 方法用于通过 username 查找 User 对象。 然后,创建一个 JwtUtil 工具类: ```java @Component public class JwtUtil { private String SECRET_KEY = "secret"; public String generateToken(UserDetails userDetails) { Map<String, Object> claims = new HashMap<>(); return doGenerateToken(claims, userDetails.getUsername()); } private String doGenerateToken(Map<String, Object> claims, String subject) { Date now = new Date(); Date expirationDate = new Date(now.getTime() + 3600000); return Jwts.builder() .setClaims(claims) .setSubject(subject) .setIssuedAt(now) .setExpiration(expirationDate) .signWith(SignatureAlgorithm.HS512, SECRET_KEY) .compact(); } public boolean validateToken(String token, UserDetails userDetails) { final String username = extractUsername(token); return (username.equals(userDetails.getUsername()) && !isTokenExpired(token)); } private boolean isTokenExpired(String token) { final Date expiration = extractExpiration(token); return expiration.before(new Date()); } private Date extractExpiration(String token) { return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getExpiration(); } private String extractUsername(String token) { return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getSubject(); } } ``` 该工具类用于生成和验证 JWT Token。其中,`generateToken` 方法用于生成 Token,`validateToken` 方法用于验证 Token 是否有效。 接下来,创建一个 AuthService 接口: ```java public interface AuthService { User register(User user); String login(String username, String password); } ``` 该接口定义了注册和登录两个方法。 然后,创建一个 AuthServiceImpl 实现类: ```java @Service public class AuthServiceImpl implements AuthService { @Autowired private AuthenticationManager authenticationManager; @Autowired private UserRepository userRepository; @Autowired private JwtUtil jwtUtil; @Override public User register(User user) { String encodedPassword = new BCryptPasswordEncoder().encode(user.getPassword()); user.setPassword(encodedPassword); return userRepository.save(user); } @Override public String login(String username, String password) { try { authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password)); } catch (Exception e) { throw new RuntimeException("Invalid username or password"); } final UserDetails userDetails = new User(userRepository.findByUsername(username).getUsername(), userRepository.findByUsername(username).getPassword(), new ArrayList<>()); return jwtUtil.generateToken(userDetails); } } ``` 该实现类中,`register` 方法用于注册用户,将密码进行加密处理后保存到数据库中;`login` 方法用于登录,通过验证用户名和密码后生成 Token 并返回。 最后,创建一个 UserController 类: ```java @RestController @RequestMapping("/api") public class UserController { @Autowired private AuthService authService; @PostMapping("/register") public ResponseEntity<?> register(@RequestBody User user) { authService.register(user); return ResponseEntity.ok("User registered successfully"); } @PostMapping("/login") public ResponseEntity<?> login(@RequestBody Map<String, String> loginData) { String username = loginData.get("username"); String password = loginData.get("password"); String token = authService.login(username, password); return ResponseEntity.ok(token); } } ``` 该类中,`register` 方法用于注册用户,接受一个 User 对象作为参数;`login` 方法用于登录,接受一个包含用户名和密码的 Map 对象作为参数。 现在,启动应用程序,并使用 Postman 或其他工具测试接口。可以使用 `/api/register` 接口注册用户,使用 `/api/login` 接口登录,并将返回的 Token 作为请求头中的 Authorization 参数访问其他受保护的接口。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值