如何以 ManyToMany (RDBMS) 的形式加入两个集合 spring-data-mongodb

Posted

技术标签:

【中文标题】如何以 ManyToMany (RDBMS) 的形式加入两个集合 spring-data-mongodb【英文标题】:How can I join two collections spring-data-mongdb as ManyToMany (RDBMS) 【发布时间】:2017-05-22 22:16:59 【问题描述】:

我有来自https://github.com/szerhusenBC/jwt-spring-security-demo/ 的这个示例示例,我正在尝试使用 mongodb 作为我的后端,但由于JwtUserFactory.java 中的代码而出现错误

return authorities.stream()
                .map(authority -> new SimpleGrantedAuthority(authority.getName().name()))
                .collect(Collectors.toList());

这是因为 model.security 包中的 AuthorityUser 类使用 RDBMS 连接,但我使用的是 mongodb 并在我的代码中出错。我为 Mongodb 定义了 AuthorityUser,如下所示。谁能指导我开始工作

Authority.java

@Document(collection = "authority")
public class Authority 

    @Id
    private Long id;

    private AuthorityName name;

    @DBRef(lazy = true)
    private List<User> users;

    public Long getId() 
        return id;
    

    public void setId(Long id) 
        this.id = id;
    

    public AuthorityName getName() 
        return name;
    

    public void setName(AuthorityName name) 
        this.name = name;
    

    public List<User> getUsers() 
        return users;
    

    public void setUsers(List<User> users) 
        this.users = users;
    

User.java

@Document(collection = "user")
public class User 

    @Id
    private Long _id;

    private String username;

    private String password;

    private String firstname;

    private String lastname;

    private String email;

    private Boolean enabled;

    private Date lastPasswordResetDate;

    @DBRef(lazy = true)
    private List<Authority> authorities;

    public Long getId() 
        return _id;
    

    public void setId(Long id) 
        _id = id;
    

    public String getUsername() 
        return username;
    

    public void setUsername(String username) 
        this.username = username;
    

    public String getPassword() 
        return password;
    

    public void setPassword(String password) 
        this.password = password;
    

    public String getFirstname() 
        return firstname;
    

    public void setFirstname(String firstname) 
        this.firstname = firstname;
    

    public String getLastname() 
        return lastname;
    

    public void setLastname(String lastname) 
        this.lastname = lastname;
    

    public String getEmail() 
        return email;
    

    public void setEmail(String email) 
        this.email = email;
    

    public Boolean getEnabled() 
        return enabled;
    

    public void setEnabled(Boolean enabled) 
        this.enabled = enabled;
    

    public List<Authority> getAuthorities() 
        return authorities;
    

    public void setAuthorities(List<Authority> authorities) 
        this.authorities = authorities;
    

    public Date getLastPasswordResetDate() 
        return lastPasswordResetDate;
    

    public void setLastPasswordResetDate(Date lastPasswordResetDate) 
        this.lastPasswordResetDate = lastPasswordResetDate;
    

UserRepository.java

public interface UserRepository extends MongoRepository<User, Double> 
    User findByUsername(String username);

例外

以下是我得到的异常

    org.springframework.security.authentication.InternalAuthenticationServiceException: null
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:126) ~[spring-security-core-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:144) ~[spring-security-core-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174) ~[spring-security-core-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.parkcity.security.controller.AuthenticationRestController.createAuthenticationToken(AuthenticationRestController.java:44) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_111]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_111]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_111]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_111]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:220) ~[spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134) ~[spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116) ~[spring-webmvc-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) ~[spring-webmvc-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) ~[spring-webmvc-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) ~[spring-webmvc-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.6.jar:8.5.6]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101) [spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127) ~[spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) ~[spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115) ~[spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.parkcity.security.JwtAuthenticationTokenFilter.doFilterInternal(JwtAuthenticationTokenFilter.java:58) [classes/:na]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177) [spring-security-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) [spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) [spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:89) [spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) [spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) [spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:784) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1410) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_111]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_111]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.6.jar:8.5.6]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_111]
Caused by: java.lang.NullPointerException: null
    at org.parkcity.security.JwtUserFactory.mapToGrantedAuthorities(JwtUserFactory.java:31) ~[classes/:na]
    at org.parkcity.security.JwtUserFactory.create(JwtUserFactory.java:24) ~[classes/:na]
    at org.parkcity.security.service.JwtUserDetailsServiceImpl.loadUserByUsername(JwtUserDetailsServiceImpl.java:25) ~[classes/:na]
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:114) ~[spring-security-core-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    ... 93 common frames omitted

2017-01-13 00:04:11.543 DEBUG 30067 --- [nio-8080-exec-1] o.s.s.w.a.ExceptionTranslationFilter     : Calling Authentication entry point.
2017-01-13 00:04:11.544 DEBUG 30067 --- [nio-8080-exec-1] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@12337118
2017-01-13 00:04:11.544 DEBUG 30067 --- [nio-8080-exec-1] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed

【问题讨论】:

你得到什么错误?您拥有的代码看起来不像将加入任何集合。 @SagarReddy 请查看更新 【参考方案1】:

基本上,您的代码存在不止一个问题。首先,您所指的项目是基于 JPA(即关系数据库)创建的,如果您想使用与 Mongo DB(文档存储)相同的代码库,至少您需要重新考虑数据模型(用户和权威)。但首先让我们试着让这个例子工作,最后我只是建议什么也可以改变。

首先,如果您使用 MongoDb 以获得最佳体验,域对象 id 字段应该具有 String 类型,因为您知道 mongodb 将 id 存储为 ObjectId bson 类型,无法转换为 Long。所以首先把 User.java 改成

@Document(collection = "user")
public class User 

    @Id
    private String _id;

    // bla bla bla

与权威对象相同

@Document(collection = "authority")
public class Authority 

    @Id
    private String _id;

    // TODO remove this right now !!! :)
    @DBRef(lazy = true)
    private List<User> users;

    // bla bla bla

和用户存储库

public interface UserRepository extends MongoRepository<User, String> 
    User findByUsername(String username);

在这两个更改之后,您还需要重构引用。

您有权威机构对用户的引用吗? !!!那是什么 ? :) 那是来自 JPA 的东西,对于 MongoDb,这个引用毫无意义。删除它!

该项目的下一件事是它依赖于一个事实,即数据存储有一些预定义的数据,请参阅import.sql,因此对于 MongoDb,您需要将数据导入 mongodb 才能运行该项目。我已经将import.sql转换成MongoShell格式,方便大家使用。

将此插入authority 集合:

 
   "_id" : ObjectId("587cb19d1db2732183afb0a9"), 
   "_class" : "org.parkcity.model.security.Authority", 
   "name" : "ROLE_ADMIN"

 
   "_id" : ObjectId("587cb19d1db2732183afb0aa"), 
   "_class" : "org.parkcity.model.security.Authority", 
   "name" : "ROLE_USER"

将此插入user 集合:

 
   "_id" : ObjectId("587cb19d1db2732183afb0ab"), 
   "_class" : "org.parkcity.model.security.User", 
   "username" : "admin", 
   "password" : "$2a$08$lDnHPz7eUkSi6ao14Twuau08mzhWrL4kyZGGU5xfiGALO/Vxd5DOi", 
   "firstname" : "admin", 
   "lastname" : "admin", 
   "email" : "admin@admin.com", 
   "enabled" : true, 
   "lastPasswordResetDate" : ISODate("2017-01-16T11:42:21.537+0000"), 
   "authorities" : [
       DBRef("authority", ObjectId("587cb19d1db2732183afb0a9")), 
       DBRef("authority", ObjectId("587cb19d1db2732183afb0aa"))
   ]
 
  
   "_id" : ObjectId("587cb1a11db2732183afb0ac"), 
   "_class" : "org.parkcity.model.security.User", 
   "username" : "user", 
   "password" :    "$2a$08$UkVvwpULis18S19S5pZFn.YHPZt3oaqHZnDwqbCW9pft6uFtkXKDC", 
   "firstname" : "user", 
   "lastname" : "user", 
   "email" : "user@user.com", 
   "enabled" : true, 
   "lastPasswordResetDate" : ISODate("2017-01-16T11:42:21.620+0000"), 
   "authorities" : [
       DBRef("authority", ObjectId("587cb19d1db2732183afb0aa"))
   ]

如您所见,我已将包从“org.zerhusen”调整为“org.parkcity”。

就是这样,现在您可以启动项目并进行一些测试。如您所见,我没有添加禁用用户(因此您可以自己添加)。

仅出于您对这种特殊情况的考虑,使用@DBRefs 是纯粹的邪恶:) 您在 MogoDb 上,因此将权限存储在与用户相同的集合和对象中,这样会更快。

还创建了一个功能齐全的分支(基于 MongoDB),可在此处获得 https://github.com/babltiga/jwt-spring-security-demo

【讨论】:

非常感谢您的回答。它就像一个魅力。我打算将此代码转换为微服务架构。您对当前项目如何用于微服务有任何建议或想法 我会说你需要一个微服务来进行身份验证,这是一个单一的服务,它只接受用户名/密码对并返回 JWT 令牌。对于这种特殊情况,您甚至不需要 Spring Security。对于所有其他微服务,您将需要 Spring Security,这将确保 JWT 令牌有效并且该用户有权访问该服务。像这样的东西.... :)【参考方案2】:

作为基于文档的存储,Mongodb 需要不同于您在 SQL 中习惯的建模思维方式。

在上面的例子中,由于权威是一个很小的对象,我只需要包含一个

List<String> authorities

在用户中。这样您就拥有了一个集合,而无需保持引用完整性并提高性能。

缺点是在更改权限时,即在重命名或删除时,您需要更新所有用户文档,但判断您的数据模型,这不会经常发生。

【讨论】:

以上是关于如何以 ManyToMany (RDBMS) 的形式加入两个集合 spring-data-mongodb的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django 中一次将多个对象添加到 ManyToMany 关系?

在arcgis中如何生成一个凹多边形或面域的形心?

如何编写通用 SQL 查询以与所有 RDBMS(Oracle、SQL 服务器、MySql、DB2 等等)兼容的 (YYYY-MM-DD) 形式提取日期

EclipseLink 如何使用两个@OneToMany 和@ManyToOne 来替换@ManyToMany

如何在typeORM中保存@ManyToMany中的关系

如何使用 @ManyToMany 审核 @JoinTable