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;
    

AuthUserDetailsS​​ervice |自定义 UserDetailsS​​ervice

// 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从数据库获取用户ID

Spring Security权限缓存

当用户注销时,Spring Security 从数据库中删除会话

如何从 Grails 中的 Spring Security 获取普通密码或解密密码?

Spring security oauth2 - 从 OAuth2 主体获取自定义数据

Spring security - 资源 j_spring_security_check 不可用