Spring Security从数据库获取用户ID

2024-06-19

我正在使用 spring security 进行身份验证并成功获得User目的 (org.springframework.security.core.userdetails.User)任何我需要的地方。

但我想要UserId还有,春天里没有的User目的。所以我创建了自己的对象(com.app.site.pojo.User)。它有一些额外的变量,例如userId,用户出生日期等等。现在我希望 spring security 使用我的user物体代替弹簧User目的。它应该包含有关该用户的所有详细信息。

我尝试将用户对象类型转换为我的对象,它抛出异常(很明显)。

我不想再次进行数据库调用以再次从数据库获取用户ID。

我怎样才能实现它?


更好的方法是创建一个 UserDetailsS​​ervice,它返回一个扩展您的 Object 类型并实现 UserDetails 的对象。这意味着您只需要执行一次数据库查找。

通过让 loadUserByUsername 的结果实现 UserDetails 并扩展您的 User 对象,您可以将其称为自定义用户对象,并且 Spring Security 可以将其称为 UserDetails。

例如:

@Service
public class UserRepositoryUserDetailsService implements UserDetailsService {
    private final UserRepository userRepository;

    @Autowired
    public UserRepositoryUserDetailsService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {
        User user = userRepository.findByEmail(username);
        if(user == null) {
            throw new UsernameNotFoundException("Could not find user " + username);
        }
        return new UserRepositoryUserDetails(user);
    }

    private final static class UserRepositoryUserDetails extends User implements UserDetails {

        private UserRepositoryUserDetails(User user) {
            super(user);
        }

        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return AuthorityUtils.createAuthorityList("ROLE_USER");
        }

        @Override
        public String getUsername() {
            return getEmail();
        }

        @Override
        public boolean isAccountNonExpired() {
            return true;
        }

        @Override
        public boolean isAccountNonLocked() {
            return true;
        }

        @Override
        public boolean isCredentialsNonExpired() {
            return true;
        }

        @Override
        public boolean isEnabled() {
            return true;
        }

        private static final long serialVersionUID = 5639683223516504866L;
    }
}

然后,您可以在配置中引用自定义 UserDetailsS​​ervice。例如:

<security:authentication-manager>
  <security:authentication-provider user-service-ref="customUserDetails" />
</security:authentication-manager>
<bean id="customUserDetails" class="sample.UserRepositoryUserDetailsService"/>

如果您使用的是 Spring Security 3.2.x+,您可以使用 Spring Security 的@AuthenticationPrincipal http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#mvc-authentication-principal解析自定义用户对象。例如:

@RequestMapping("/messages/inbox")
public ModelAndView findMessagesForUser(@AuthenticationPrincipal CustomUser customUser) {

    // .. find messags for this user and return them ...
}

否则您可以使用以下内容:

@RequestMapping("/messages/inbox")
public ModelAndView findMessagesForUser(Authentication auth) {
        User customUser = (User) auth.getPrincipal();
     ...
}

如果使用 XML 配置,您将需要向 Spring MVC 注册 AuthenticationPrincipalArgumentResolver。

<mvc:annotation-driven>
  <mvc:argument-resolvers>
    <beans:bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver"/>
  </mvc:argument-resolvers>
</mvc:annotation-driven>

您可以在我的文章中找到有关此内容的详细信息github 示例项目 https://github.com/rwinch/gs-spring-security-3.2/。 README 也参考录制的网络研讨会 https://spring.io/blog/2014/01/21/webinar-replay-spring-security-3-2.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Security从数据库获取用户ID 的相关文章

随机推荐