Spring Security:从数据库表中获取当前用户的字段
Posted
技术标签:
【中文标题】Spring Security:从数据库表中获取当前用户的字段【英文标题】:Spring Security : get the current user's fields from a database table 【发布时间】:2021-01-23 01:00:07 【问题描述】:我的数据库中有一个包含此类信息的表:
Nom = 名称。 Prénom = 名字。
我正在尝试,一旦用户登录,检索整个用户的字段,除了:密码。
例如,
如果我在登录页面上输入我的用户名和密码,我想找回:
我的名字 我的名字 我的电子邮件 我的用户名还有,
我已经知道如何简单地检索用户名,但是我无法获取整个用户的字段..
这是我的文件,
用户实体
@Entity
@Table(name = "users")
@NoArgsConstructor
@Getter @Setter
public class User
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "nom", length = 50)
private String name;
@Column(name = "prenom", length = 50)
private String firstname;
@Column(name = "username", length = 50, unique = true)
private String username;
@Column
private String email;
@Column
private String role;
@Column()
private String password;
AuthUserDetails |自定义用户详细信息
public class AuthUserDetails implements UserDetails
private final String name;
private final String firstname;
private final String username;
private final String email;
private final String password;
private final List<GrantedAuthority> authorities;
public AuthUserDetails(User user)
this.name = user.getUsername();
this.firstname = user.getFirstname();
this.username = user.getUsername();
this.email = user.getEmail();
this.password = user.getPassword();
this.authorities = Arrays.stream(user.getRole().split(","))
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
@Override
public Collection<? extends GrantedAuthority> getAuthorities()
return authorities;
@Override
public String getPassword()
return password;
@Override
public String getUsername()
return username;
@Override
public boolean isAccountNonExpired()
return true;
@Override
public boolean isAccountNonLocked()
return true;
@Override
public boolean isCredentialsNonExpired()
return true;
@Override
public boolean isEnabled()
return true;
AuthUserDetailsService |自定义 UserDetailsService
// Handle UserAuthentication from Database | Personal User's credentials
@Service
public class AuthUserDetailsService implements UserDetailsService
private final UserRepository userRepository;
@Autowired
public AuthUserDetailsService(UserRepository userRepository)
this.userRepository = userRepository;
// ************************ By | Username ************************ //
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
// Find the username in the DB
Optional<User> user = userRepository.findByUsername(username);
user.orElseThrow(() -> new UsernameNotFoundException("Not found " + username));
return user.map(AuthUserDetails::new).get();
用户服务
@Service
public class UserService
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final AuthenticationManager authenticationManager;
private final JwtProvider jwtProvider;
@Autowired
public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder,
AuthenticationManager authenticationManager, JwtProvider jwtProvider)
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
this.authenticationManager = authenticationManager;
this.jwtProvider = jwtProvider;
// ****************************** Login ***************************** //
public AuthenticationResponse login(AuthMapping authMapping)
Authentication authenticate = authenticationManager.authenticate(new
UsernamePasswordAuthenticationToken(authMapping.getUsername(), authMapping.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authenticate);
String authenticationToken = jwtProvider.generateToken(authenticate);
return new AuthenticationResponse(authenticationToken, authMapping.getUsername());
授权映射 |这是用户输入的登录内容
@Getter @Setter
public class AuthMapping
private String username;
private String password;
身份验证响应 |这是我们成功登录后检索到的内容
@Data
@AllArgsConstructor
public class AuthenticationResponse
private String authenticationToken;
private String username;
安全配置
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
// *************************************************************************** //
private final UserDetailsService userDetailsService;
private final PasswordEncoder passwordEncoder;
private final JwtAuthenticationFilter jwtAuthenticationFilter;
@Autowired
public SecurityConfig(@Qualifier("authUserDetailsService") UserDetailsService userDetailsService, PasswordEncoder passwordEncoder, JwtAuthenticationFilter jwtAuthenticationFilter)
this.userDetailsService = userDetailsService;
this.passwordEncoder = passwordEncoder;
this.jwtAuthenticationFilter = jwtAuthenticationFilter;
// *************************************************************************** //
// Authorization
@Override
protected void configure(HttpSecurity http) throws Exception
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/users/register").permitAll()
.antMatchers("/api/users/login").permitAll()
.anyRequest().authenticated();
// JWT Authentication
http.addFilterBefore(this.jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
// CORS
http.addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class);
// *************************************************************************** //
/**
* Handle The Authentication in Spring | InMemory/LDAP/JDBC
* The handle is made through a service : UserDetailsService
*/
@Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(this.passwordEncoder);
/*
* Read user from the database
* Spring needs to decode the password before performing the authentication
*/
// *************************************************************************** //
@Bean(BeanIds.AUTHENTICATION_MANAGER)
@Override
protected AuthenticationManager authenticationManager() throws Exception
return super.authenticationManager();
用户控制器 |登录
// User | Login
@PostMapping("/login")
public AuthenticationResponse login(@RequestBody AuthMapping authMapping)
return userService.login(authMapping);
请问如何解决?
提前谢谢你。
【问题讨论】:
【参考方案1】:您可以编写另一个自定义方法来检索结果: 我展示了我用 Kotlin 编写的一段代码。
fun currentUser(): UserDto
val auth = SecurityContextHolder.getContext().authentication
//auth.principal this is username
val optional = repository.findByEmail(auth.principal.toString())
if (!optional.isPresent) throw ErrorWithUserTokenException(auth.principal.toString())
return UserDto.toDto(optional.get())
data class UserDto(
var id: Long,
var username: String
)
companion object
fun toDto(user: User): UserDto
return user.run UserDto(id!!, username)
我认为,至少,这个答案给了你一个解决问题的想法:)
【讨论】:
好的。祝你好运!如果我的回答对你有用,我很高兴! @Finalmix6以上是关于Spring Security:从数据库表中获取当前用户的字段的主要内容,如果未能解决你的问题,请参考以下文章
当用户注销时,Spring Security 从数据库中删除会话
如何从 Grails 中的 Spring Security 获取普通密码或解密密码?