Spring Boot为什么每次请求还能从SecurityContextHolder中获取用户信息呢?
时间: 2024-05-22 09:12:44 浏览: 10
Spring Security使用ThreadLocal存储SecurityContext对象,该对象包含了当前用户的认证信息和授权信息。在Spring Boot中,每个请求都会创建一个新的线程,因此每个请求都有自己的SecurityContext对象。在处理请求时,Spring Security会从当前线程的SecurityContextHolder中获取SecurityContext对象,然后从中获取当前用户的认证信息和授权信息。
因此,即使在同一个请求中,不同的方法或组件也可以通过SecurityContextHolder获取到当前用户的信息。这种方式可以方便地实现权限控制和安全验证,避免了在每个方法或组件中都需要手动获取和验证用户信息的麻烦。
相关问题
基于Spring Boot的用户权限管理系统的设计与实现用到的函数
### 回答1:
在基于Spring Boot的用户权限管理系统中,我们可能会使用到以下函数:
1. @GetMapping、@PostMapping、@PutMapping、@DeleteMapping:这些注解用于定义HTTP请求的方法类型,即GET、POST、PUT和DELETE。
2. @RequestMapping:这个注解用于定义HTTP请求的URL地址和方法类型,常用的方法类型包括GET、POST、PUT、DELETE、HEAD、OPTIONS和PATCH等。
3. @RestController:这个注解用于定义一个RESTful风格的控制器,它会自动将控制器中的方法返回的对象转换为JSON格式的响应数据。
4. @RequestBody:这个注解用于将HTTP请求的JSON格式的请求体解析为Java对象。
5. @ResponseBody:这个注解用于将Java对象转换为JSON格式的响应数据。
6. @PathVariable:这个注解用于将URL路径中的变量解析为方法参数。
7. @RequestParam:这个注解用于将HTTP请求的查询参数解析为方法参数。
8. @Autowired:这个注解用于自动装配Bean对象,可以用在类成员变量、构造方法、Setter方法上。
9. @Service:这个注解用于定义一个业务逻辑层的Bean对象。
10. @Repository:这个注解用于定义一个数据访问层的Bean对象。
11. @Transactional:这个注解用于定义一个具有事务管理功能的方法,可以保证方法执行过程中出现异常时自动回滚事务。
12. SecurityContextHolder.getContext().getAuthentication():这个函数用于获取当前用户的认证信息,包括用户名、密码、角色等。
13. BCryptPasswordEncoder.encode():这个函数用于对密码进行加密。
14. BCryptPasswordEncoder.matches():这个函数用于判断输入的密码是否与加密后的密码匹配。
15. Pageable:这个类用于定义分页查询的参数,包括页数、每页数据条数、排序方式等。
16. Page:这个类用于封装分页查询的结果,包括数据列表、当前页码、总页数、总数据条数等。
### 回答2:
基于Spring Boot的用户权限管理系统的设计与实现主要用到以下几个函数:
1. 用户注册:设计并实现一个register()函数,用于处理用户的注册请求。该函数将接收用户提交的注册信息(如用户名、密码等),并对其进行校验和处理(如检查用户名是否已存在、加密密码等),最后将用户信息存储到数据库中。
2. 用户登录:设计并实现一个login()函数,用于处理用户的登录请求。该函数将接收用户提交的登录信息(如用户名、密码等),并对其进行校验和处理(如检查用户名是否存在、比对密码等),最后返回登录结果(如成功或失败)。
3. 用户权限分配:设计并实现一个assignRole()函数,用于处理管理员为用户分配角色的请求。该函数将接收管理员提交的角色分配信息(如用户ID、角色ID等),并将该用户与角色的关联信息保存到数据库中,完成用户角色分配的操作。
4. 用户权限查询:设计并实现一个getUserRoles()函数,用于查询用户的权限信息。该函数将接收用户ID作为参数,并在数据库中查询该用户的角色信息,返回用户所拥有的角色列表。
5. 角色权限查询:设计并实现一个getRolePermissions()函数,用于查询角色的权限信息。该函数将接收角色ID作为参数,并在数据库中查询该角色的权限信息,返回角色所拥有的权限列表。
6. 资源权限验证:设计并实现一个checkPermission()函数,用于对用户请求的资源进行权限验证。该函数将接收用户ID、资源路径等参数,通过查询用户所拥有的角色和角色所拥有的权限,判断用户是否有权限访问该资源,返回验证结果(如允许或拒绝)。
以上为基于Spring Boot的用户权限管理系统设计与实现中的一些主要函数,这些函数在实际开发中会进一步完善和细化,以满足具体的业务需求。
spring boot Java 写一个JWT验证用户登录账户和密码
可以的,以下是一份简单的 Spring Boot Java JWT 用户验证的代码示例。
首先,需要添加以下依赖项到 pom.xml 文件中:
```
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
```
在 Spring Boot 应用程序的配置文件中添加以下代码:
```
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsService;
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Bean
public JwtAuthenticationFilter authenticationTokenFilterBean() throws Exception {
return new JwtAuthenticationFilter();
}
@Override
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean(BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
}
}
```
在上面的代码中,我们定义了一个 SecurityConfig 类,这是一个 Spring Security 的配置。其中 @EnableWebSecurity 注释表示我们要启用 Spring Security 的 Web 安全功能。
接下来,我们需要定义一个用于验证用户身份的服务:
```
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found with username: " + username));
return UserPrincipal.create(user);
}
@Transactional
public UserDetails loadUserById(Long id) {
User user = userRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("User", "id", id));
return UserPrincipal.create(user);
}
}
```
在上面的代码中,我们定义了一个 CustomUserDetailsService 服务类,它实现了 Spring Security 的 UserDetailsService 接口。
最后,我们需要创建一个用于生成和验证 JWT 的类:
```
public class JwtTokenProvider {
@Value("${app.jwtSecret}")
private String jwtSecret;
@Value("${app.jwtExpirationInMs}")
private int jwtExpirationInMs;
public String generateToken(Authentication authentication) {
UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
Date now = new Date();
Date expiryDate = new Date(now.getTime() + jwtExpirationInMs);
return Jwts.builder()
.setSubject(userPrincipal.getId().toString())
.setIssuedAt(new Date())
.setExpiration(expiryDate)
.signWith(SignatureAlgorithm.HS512, jwtSecret)
.compact();
}
public Long getUserIdFromJWT(String token) {
Claims claims = Jwts.parser()
.setSigningKey(jwtSecret)
.parseClaimsJws(token)
.getBody();
return Long.parseLong(claims.getSubject());
}
public boolean validateToken(String authToken) {
try {
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
return true;
} catch (SignatureException ex) {
logger.error("Invalid JWT signature");
} catch (MalformedJwtException ex) {
logger.error("Invalid JWT token");
} catch (ExpiredJwtException ex) {
logger.error("Expired JWT token");
} catch (UnsupportedJwtException ex) {
logger.error("Unsupported JWT token");
} catch (IllegalArgumentException ex) {
logger.error("JWT claims string is empty.");
}
return false;
}
}
```
在上面的代码中,我们定义了一个 JwtTokenProvider 类,它提供了以下三个方法:
- generateToken:用于生成 JWT。
- getUserIdFromJWT:从 JWT 中提取用户 ID。
- validateToken:用于验证 JWT。
完整的用户登录验证代码请参考下面的例子:
```
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private JwtTokenProvider tokenProvider;
@PostMapping("/login")
public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getUsernameOrEmail(), loginRequest.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = tokenProvider.generateToken(authentication);
return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
}
@PostMapping("/register")
public ResponseEntity<?> registerUser(@Valid @RequestBody SignUpRequest signUpRequest) {
if (userRepository.existsByUsername(signUpRequest.getUsername())) {
return new ResponseEntity(new ApiResponse(false, "Username is already taken!"), HttpStatus.BAD_REQUEST);
}
if (userRepository.existsByEmail(signUpRequest.getEmail())) {
return new ResponseEntity(new ApiResponse(false, "Email Address already in use!"), HttpStatus.BAD_REQUEST);
}
// Creating user's account
User user = new User(signUpRequest.getName(), signUpRequest.getUsername(),
signUpRequest.getEmail(), signUpRequest.getPassword());
user.setPassword(passwordEncoder.encode(user.getPassword()));
User result = userRepository.save(user);
URI location = ServletUriComponentsBuilder.fromCurrentContextPath().path("/api/users/{username}")
.buildAndExpand(result.getUsername()).toUri();
return ResponseEntity.created(location).body(new ApiResponse(true, "User registered successfully"));
}
}
```
在上面的代码中,我们定义了一个 AuthController 类,该类包含了用户登录和注册的方法。其中,authenticateUser 方法用于验证用户登录,registerUser 方法用于用户注册。
登录验证请求发送到 /api/auth/login URL,注册请求发送到 /api/auth/register URL。
登录请求使用用户名或电子邮件,以及密码作为参数。如果验证成功,将生成 JWT 并在响应体中返回。
注册请求使用名称、用户名、电子邮件和密码作为参数,在保存用户到数据库之前对数据进行验证。
至此,我们已经实现了一个简单的 Spring Boot Java JWT 用户验证的应用程序。
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)