spring security get user id from DB

前端 未结 4 2060
南旧
南旧 2021-02-06 16:10

I am using spring security for authentication and successfully able to get User object (org.springframework.security.core.userdetails.User) anywhere I

相关标签:
4条回答
  • 2021-02-06 16:21

    I was in the same situation as you, what I did was redirect the user to a new page after login, and create a controller function of that page, to get the user from DB and store his id as a Session Variable.

        @RequestMapping(value = { "/overview" }, method = RequestMethod.GET)
        public ModelAndView overViewPage(HttpServletRequest request) {
    
            ModelAndView model = new ModelAndView();
            model.addObject("title", "Spring Security + Hibernate Example");
            model.addObject("message", "This is default page!");
            model.setViewName("hello");
    
    
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            UserDetails userDetail = (UserDetails) auth.getPrincipal();
    
            User u = userService.getUser(userDetail.getUsername());
            request.getSession().setAttribute("userId", u.getId());
    
            return model;
    
        }
    

    You can use the user object or just use his id for future queries by doing

    int userId = (int) request.getSession().getAttribute("userId");
    

    My userService is just a simple service

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import com.sports.dao.UserDao;
    
    @Service
    @Transactional
    public class UserServiceImpl implements UserService{
    
        @Autowired
        private UserDao userDao;
    
        public com.sports.models.User getUser(String username){
            return userDao.findByUserName(username);
        }
    
    }
    

    I'm also new to spring so I'm not sure if this is the best way to do it.

    0 讨论(0)
  • 2021-02-06 16:23
    <bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
      <property name="userDetailsService" ref="customUserDetailsService" />
    </bean>
    

    customUserDetailsService will override loadUserByUsername like below

    @Override
    public UserDetails loadUserByUsername(String username) {
    return customUser;
    // where customUser extends org.springframework.security.core.userdetails.User
    }
    

    You can have custom fields under customUser

    0 讨论(0)
  • 2021-02-06 16:24

    A better way of doing this is to create a UserDetaisService that returns an object that extends your type of Object and implements UserDetails. This means you only need to perform one database lookup.

    By having the result of loadUserByUsername implement UserDetails and extend your User object, you can refer to it as the custom user object and Spring Security can refer to it as a UserDetails.

    For example:

    @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;
        }
    }
    

    You can then refer to the custom UserDetailsService in your configuration. For example:

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

    If you are using Spring Security 3.2.x+ you can use Spring Security's @AuthenticationPrincipal to resolve the custom user object. For example:

    @RequestMapping("/messages/inbox")
    public ModelAndView findMessagesForUser(@AuthenticationPrincipal CustomUser customUser) {
    
        // .. find messags for this user and return them ...
    }
    

    Otherwise you can use the following:

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

    If using the XML configuration, you will need to register AuthenticationPrincipalArgumentResolver with Spring MVC.

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

    You can find details about this in my github sample project. The README also reference the recorded webinar.

    0 讨论(0)
  • 2021-02-06 16:29
    @RequestMapping(value="/getLogedUserid")
    public Long getUserByUsername(HttpServletRequest httpServletRequest) {      
        HttpSession httpSession = httpServletRequest.getSession();
        SecurityContext securityContext = (SecurityContext)
                httpSession.getAttribute("SPRING_SECURITY_CONTEXT");
        String username = securityContext.getAuthentication().getName();
        return userMetier.getUserByUsername(username);
    }
    

    here we have the definition of the function getting the id by the username

        @Override
    public Long getUserByUsername(String Username) {
        User user = userRepository.getUserByUsername(Username);
    
        return user.getIdUser();
    }
    
    0 讨论(0)
提交回复
热议问题