spring security从DB获取用户ID
我使用spring security进行身份validation,并成功地在任何需要的地方获取User
对象( org.springframework.security.core.userdetails.User
)。
但我也想要UserId
,这在spring的User
对象中不存在。 所以我创建了自己的对象( com.app.site.pojo.User
)。 它有很少的额外变量,如userId , 用户出生日期等。现在我希望spring security使用我的user
对象而不是spring User
对象。 它应该包含有关该用户的所有详细信息。
我试图将用户对象的类型转换为我的对象,它抛出exception(很明显)。
我不想再次调用DB来再次从DB获取userId。
我怎样才能实现它?
我和你的情况相同,我做的是在登录后将用户重定向到新页面,并创建该页面的控制器function,以便从DB获取用户并将其id存储为会话变量 。
@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; }
您可以使用用户对象或只是使用他的ID进行将来的查询
int userId = (int) request.getSession().getAttribute("userId");
我的userService只是一个简单的服务
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); } }
我也是新手,所以我不确定这是不是最好的方法。
更好的方法是创建一个UserDetaisService,它返回一个扩展您的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; } }
然后,您可以在配置中引用自定义UserDetailsService。 例如:
如果您使用的是Spring Security 3.2.x +,则可以使用Spring Security的@AuthenticationPrincipal来解析自定义用户对象。 例如:
@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。
您可以在我的github示例项目中找到有关此内容的详细信息。 自述文件还参考了录制的网络研讨会 。
customUserDetailsService将覆盖loadUserByUsername,如下所示
@Override public UserDetails loadUserByUsername(String username) { return customUser; // where customUser extends org.springframework.security.core.userdetails.User }
您可以在customUser下拥有自定义字段
@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); }
这里我们有通过用户名获取id的函数的定义
@Override public Long getUserByUsername(String Username) { User user = userRepository.getUserByUsername(Username); return user.getIdUser(); }
- 我应该同时使用SocialAuthenticationFilter和ProviderSignInController吗?
- @RolesAllowed总是在Jersey资源上拒绝(禁止)
- JDBC中缺少dll
- 使用AuthenticationFailureHandler在Spring Security中自定义身份validation失败响应
- Spring Security 4.0.0 + ActiveDirectoryLdapAuthenticationProvider + BadCredentialsException PartialResultException
- Spring Security,表单登录和并发会话
- HTTPS URL的基本代理身份validation返回HTTP / 1.0 407需要代理身份validation
- Spring SecurityContext在错误页面上返回null身份validation
- 将数据从PHP发送到Java应用程序