在业务系统中很可能遇到两个或者用户体系,比如后台管理用户和前台APP用户。很多时候这两种用户走的还是两种不同的体系,比如后台用户用有状态的Session,而前台用户用流行的无状态JWT,总之它们是两种完全不同的隔离体系。这种需求该怎么实现呢?其中有哪些坑要踩呢?本文将告诉你怎么做。,在Spring Security中当然是按照不同的请求路径规则定义专门的过滤器链,你可以通过三种方式来实现路径拦截。然后按照策略定义过滤器链即可:,这三种策略介绍如下。,你可以通过HttpSecurity提供的过滤器过滤URI,例如拦截请求中在query参数而且包含id的URI:,这种常用来匹配一些带参数的URL。,这种是我们常见的方式,例如拦截/system开头的所有路径:,关于这种方式这里不再赘述,详细可以通过Ant规则详解这一篇来了解。,一些复杂的组合可以通过定义RequestMatcher接口来组合,例如这种复杂的规则:,满足三个路径中的一个就行,这种组合方式能够实现最复杂的拦截策略。,这里还要注意配置之间的隔离。,默认情况下的Session依赖于cookie中设定的jsessionid, 如果你使用会话模式,必须隔离多个过滤器链的会话存储,这样能够实现一个多个过滤器在同一个会话下不同的登录状态,否则它们共享配置就会发生错乱。,这是因为在一个会话下,默认的属性Key是SPRING_SECURITY_CONTEXT,当在同一个会话下(同一个浏览器不同的tab页)获取当前上下文都是这样的:,这样登录一个,其它都认为是登录状态,这显然不符合预期。你需要在不同的过滤器中定义不同的会话属性Key。,无状态Token相对简单一些,前端根据路径分开存储即可,而且Token中应该包含校验过滤器链的信息以方便后端校验,避免Token混用。,如果你的不同端的用户是独立的,你需要实现不同的UserDetailsService,但是存在多个UserDetailsService的话,,一定不要将它们直接注册到Spring IoC中!,一定不要将它们直接注册到Spring IoC中!,一定不要将它们直接注册到Spring IoC中!,如果你一定要注册到Spring IoC,你需要定义独立的接口,就像这样:,然后实现该接口再注入Spring IoC,每个过滤器链配置的时候就可以这样写:,但是Spring IoC中必须有一个UserDetailsService,你得这样写:,为啥不可用,因为注入Spring IoC的UserDetailsService是一个兜底的实现,如果你只有一个实现,放入Spring IoC无可厚非,如果你想让多个各自走各自的就必须这样写最安全,不然还有一个默认的InMemoryUserDetailsManager也会生效成为兜底的。,其它配置按照各自的配置就行了,目前我还没有发现有冲突的地方。上面所讲的东西,在Id Server授权服务器中就是这样实现授权服务器过滤、后台管理用户和前台授权用户三者之间隔离的:,你可以通过https://github.com/NotFound403/id-server下载源码进行改造学习,欢迎Star。
© 版权声明
文章版权归作者所有,未经允许请勿转载。