在Spring Boot中,获取登录用户的个人信息通常需要使用spring Security框架来进行身份认证和授权。Spring Security提供了一个名为SecurityContextHolder的上下文对象,它包含了当前请求的身份
在Spring Boot中,获取登录用户的个人信息通常需要使用spring Security框架来进行身份认证和授权。Spring Security提供了一个名为SecurityContextHolder的上下文对象,它包含了当前请求的身份认证信息。通过SecurityContextHolder,可以访问当前已认证的用户的信息。
当使用 Spring Boot + Spring Security 构建 WEB 应用程序时,我们需要定义用户实体类来存储用户信息。以下是一个基本的 User
实体类
@Entity@Table(name = "users")public class User implements UserDetails { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false, unique = true) private String username; @Column(nullable = false) private String passWord; @Column(nullable = false) private String fullName; @Column(nullable = false, unique = true) private String email; // 用户角色定义为一个字符串,用逗号分隔 @Column(nullable = false) private String roles; // 其他字段和方法 // UserDetails 方法的实现 @Override public Collection extends GrantedAuthority> getAuthorities() { return Arrays.stream(roles.split(",")) .map(SimpleGrantedAuthority::new) .collect(Collectors.toList()); } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; }}
在这个例子中,User
实体类使用 @Entity
和 @Table
注解进行了标记,表明它是一个 JPA 实体类,并且对应了一个名为 users
的数据库表。实体类中包含了一些基本的属性,例如 id
、username
、password
、fullName
和 email
。另外,roles
属性定义了用户的角色,这是一个字符串,多个角色之间用逗号分隔。
User
实体类实现了 UserDetails
接口,该接口包含了一些必须实现的方法,用于获取用户的授权信息。在 getAuthorities()
方法中,我们将用户的角色字符串分割成多个角色,并将其转换为 Spring Security 中的 GrantedAuthority
对象。其余的方法返回的都是 true
,表示这些限制条件都没有被启用。
你还可以根据你的业务需求对 User
实体类进行扩展或修改。
要获取已认证用户的信息,可以在控制器方法中注入Authentication对象,然后从该对象中获取用户信息。例如:
import org.springframework.security.core.Authentication;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class UserController { @GetMapping("/me") public UserDetails getUserDetails(Authentication authentication) { return (UserDetails) authentication.getPrincipal(); }}
在上面的代码中,使用@GetMapping注解将控制器方法映射到“/me”路径。方法中注入Authentication对象,并从该对象中获取Principal,即已认证用户的信息。由于Spring Security默认使用UserDetailsService来加载用户信息,因此Principal通常是UserDetails对象。
如果您想要访问更多的用户信息,可以自定义一个UserDetailsService,通过UserDetailsService从数据库或其他数据源中加载用户信息。然后,您可以通过从Principal中获取用户名或其他标识符来检索用户信息。
当使用Spring Security进行身份认证时,需要实现UserDetailsService接口来加载用户信息。UserDetailsService接口只有一个方法:loadUserByUsername,该方法返回一个实现了UserDetails接口的对象,该对象包含有关用户的信息。
下面是一个简单的UserDetailsService类的示例,它从内存中的用户列表中加载用户信息:
import java.util.ArrayList;import java.util.List;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.userdetails.User;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.core.userdetails.UsernameNotFoundException;public class MyUserDetailsService implements UserDetailsService { private List users = new ArrayList<>(); public MyUserDetailsService() { users.add(new User("user1", "password1", getAuthorityList("ROLE_USER"))); users.add(new User("user2", "password2", getAuthorityList("ROLE_USER"))); users.add(new User("admin", "password", getAuthorityList("ROLE_USER", "ROLE_ADMIN"))); } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { for (User user : users) { if (user.getUsername().equals(username)) { return user; } } throw new UsernameNotFoundException("User not found with username: " + username); } private List getAuthorityList(String... roles) { List authorityList = new ArrayList<>(); for (String role : roles) { authorityList.add(new SimpleGrantedAuthority(role)); } return authorityList; }}
在上面的代码中,MyUserDetailsService类实现了UserDetailsService接口,并重写了loadUserByUsername方法。该方法首先检查用户列表中是否存在与传递的用户名匹配的用户,如果找到该用户,则将其作为UserDetails对象返回。否则,抛出UsernameNotFoundException异常。
在这个例子中,用户列表是硬编码在MyUserDetailsService类中的。在实际应用中,您将从数据库或其他数据源中获取用户信息,并在loadUserByUsername方法中使用它。此外,您还可以根据需要添加更多的用户属性,例如电子邮件地址、电话号码等。
最后,值得一提的是,在实现UserDetailsService接口时,请务必确保密码已被加密并保存为哈希值。在本示例中,密码是明文存储的,但在实际应用中,应使用Spring Security提供的密码编码器来对密码进行加密。
以下是一份完整的示例代码,包括一个自定义的UserDetailsService和Spring Security配置类:
import java.util.ArrayList;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;import org.springframework.security.config.annotation.web.builders.httpsecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.userdetails.User;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.core.userdetails.UsernameNotFoundException;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;@Configuration@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled = true)public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder()); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/user/**").hasAnyRole("ADMIN", "USER") .antMatchers("/").permitAll() .and().fORMLogin() .and().loGout().logoutSuccessUrl("/login").permitAll(); }}class MyUserDetailsService implements UserDetailsService { private List users = new ArrayList<>(); public MyUserDetailsService() { users.add(new User("user1", "$2a$10$HKV7WJB/FNH8/3wXXtGB0.bDrxPlheBlsHSDkOizQ94RyL5v5n5oy", getAuthorityList("ROLE_USER"))); users.add(new User("user2", "$2a$10$L9.Jir1vH6Wjtr8ZnI6FseV6rHdLWnV7yI0g1lV7vLmFFopW8VzU6", getAuthorityList("ROLE_USER"))); users.add(new User("admin", "$2a$10$5aJN5O5pyrgQMDR.Ta5/0.hxOeSw/3nm3q9XcVvBIzDdtyA8DPZ3C", getAuthorityList("ROLE_USER", "ROLE_ADMIN"))); } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { for (User user : users) { if (user.getUsername().equals(username)) { return user; } } throw new UsernameNotFoundException("User not found with username: " + username); } private List getAuthorityList(String... roles) { List authorityList = new ArrayList<>(); for (String role : roles) { authorityList.add(new SimpleGrantedAuthority(role)); } return authorityList; }}
上面的代码包含了一个自定义的UserDetailsService实现类和一个Spring Security配置类。以下是代码中的一些要点:
MyUserDetailsService类:这是一个自定义的UserDetailsService实现类,用于从硬编码的用户列表中加载用户信息。在loadUserByUsername方法中,根据传递的用户名
以下是使用Postman测试api接口的步骤:
打开Postman软件并创建一个新的请求。在请求的URL地址栏中输入API接口的URL,例如http://localhost:8080/user/info
点击请求方式旁边的下拉菜单,选择HTTP请求方法,例如GET方法。
在请求头(Headers)中添加必要的认证信息,例如添加一个Authorization头,其值为Bearer加上访问令牌(access token),例如Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyMSIsInJvbGUiOiJVU0VSIiwiaWF0IjoxNTE2MjM5MDIyfQ.kNqr5ZCw5vFh1dW8Kq3t_ZL-3q_kh12VTWg_w8mZisI
如果API接口需要传递请求参数,可以在请求参数(Params)中添加参数名和参数值。
点击发送按钮,发送请求并查看响应结果。
如果请求成功,可以在响应结果中看到API接口返回的数据,如果请求失败,可以查看响应状态码和错误信息来定位问题。
需要注意的是,在测试API接口时,需要了解API接口的请求参数、请求方式、认证方式等信息,并在请求头和请求参数中正确传递信息。另外,为了避免误操作,建议在测试环境中测试API接口,不要在生产环境中测试API接口
根据上面提供的代码,如果在Postman中成功请求 /user/info
接口,将会收到类似下面的 JSON 格式响应数据:
{ "id": 1, "username": "user1", "fullName": "User One", "email": "user1@example.com"}
其中,id
是用户ID,username
是用户名,fullName
是用户的全名,email
是用户的电子邮件地址。这些数据是在 UserInfo
类中定义的。
需要注意的是,如果没有授权访问该接口或者用户不存在,那么响应数据中将不会包含这些信息。如果出现这种情况,响应数据中可能会包含错误消息。
当使用 Spring Boot + Spring Security 构建 Web 应用程序时,可以使用 ResponseEntity
类来设置响应的 HTTP 状态码。ResponseEntity
类包装了 HTTP 响应的正文、HTTP 状态码以及响应头信息。它允许我们返回自定义响应实体,而不是使用默认的响应实体。
在你的代码中,你可以使用 ResponseEntity
替换原本的 UserInfo
返回类型。这样,就可以将 HTTP 状态码作为 ResponseEntity
的一部分返回到客户端。在 getUserInfo()
方法中,你可以使用以下代码返回带有状态码的响应:
@GetMapping("/user/info")public ResponseEntity getUserInfo() { // 获取当前登录用户 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication == null || !authentication.isAuthenticated()) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } // 获取用户信息并返回 String username = authentication.getName(); UserInfo userInfo = userService.getUserInfoByUsername(username); return ResponseEntity.ok(userInfo);}
在这个例子中,如果用户未授权或未经身份验证,则将返回 HTTP 401 状态码。如果用户已经经过身份验证,将返回 HTTP 200 状态码,并带有用户信息。
如果需要在 Postman 中测试 API 的响应状态码,可以在请求完成后查看响应面板的右上角,显示的是响应的状态码和消息。
在我上面已经回答针对如何使用 ResponseEntity
设置 HTTP 状态码做了说明,同时也提到了如何在 Postman 中查看响应的状态码。
在 Spring Boot 应用程序中,我们可以使用 ResponseEntity
类来包装响应实体,并指定返回的 HTTP 状态码。例如,在 getUserInfo()
方法中,我们可以使用以下代码返回带有
@GetMapping("/user/info")public ResponseEntity getUserInfo() { // 获取当前登录用户 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication == null || !authentication.isAuthenticated()) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } // 获取用户信息并返回 String username = authentication.getName(); UserInfo userInfo = userService.getUserInfoByUsername(username); return ResponseEntity.ok(userInfo);}
在这个例子中,如果用户未授权或未经身份验证,则将返回 HTTP 401 状态码。如果用户已经经过身份验证,将返回 HTTP 200 状态码,并带有用户信息。
在 Postman 中查看响应的状态码,可以在请求完成后查看响应面板的右上角,显示的是响应的状态码和消息。如果返回的状态码为200,则表示请求成功,其他状态码则表示请求失败。
CREATE TABLE `users` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT, `username` VARCHAR(50) NOT NULL, `password` VARCHAR(100) NOT NULL, `full_name` VARCHAR(100) NOT NULL, `email` VARCHAR(100) NOT NULL, `roles` VARCHAR(100) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `UK_username` (`username`), UNIQUE KEY `UK_email` (`email`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
在这个例子中,我们定义了一个名为 users
的表,它包含了以下字段:
id
:用户的唯一标识符,使用自增长的方式生成。username
:用户的登录名,必须是唯一的。password
:用户的登录密码,存储加密后的密码。full_name
:用户的全名,用于显示用户的真实姓名。email
:用户的电子邮件地址,必须是唯一的。roles
:用户的角色,以逗号分隔多个角色。在实际应用中,你可以根据需要对数据表进行修改和扩展。
来源地址:https://blog.csdn.net/weixin_39868387/article/details/129097359
--结束END--
本文标题: springboot获取登录用户的个人信息
本文链接: https://www.lsjlt.com/news/410452.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-04-03
2024-04-03
2024-04-01
2024-01-21
2024-01-21
2024-01-21
2024-01-21
2023-12-23
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0