聊聊 spring boot 后端大家如何玩权限?

2019-12-13 14:41:24 +08:00
 shazh520

前后端完全分离那就 token 了,UUID 或者 jwt,这个我估计大家都这么做;

但是前端渠道既有网页、APP 又有小程序,网页使用 thymeleaf 生成;这种情况下我用 spring security 就没法儿了,如果 token 的话,thymeleaf 这边就要憋屈一点,不能用 session,不用 token 的话 APP 和小程序又不行;

嗯哼?

6269 次点击
所在节点    Java
26 条回复
shazh520
2019-12-13 14:45:05 +08:00
因为我司前端技术储备不太够,所以前端除了 css 其他工作由我们几个后端来,有时候工期比较紧张的话就用 thymeleaf 了,不熟悉 webpack 的配置容易在上线的时候出点幺蛾子(半夜想睡的时候想 kill 人)
zhenjiachen
2019-12-13 14:46:31 +08:00
自定义 filter ,可以从 header 里面获取 token,也可以支持 session。或者直接所有的都使用 cookie,小程序和 app 应该都支持 cookie 的,引入 Spring Session 也支持分布式的。
From313
2019-12-13 14:48:03 +08:00
@zhenjiachen ios 不支持 cookie
manami
2019-12-13 14:49:51 +08:00
这种情况 redis 存 token 再适合不过了
sutra
2019-12-13 14:51:24 +08:00
我是自己实现了一个 HttpSessionIdResolver 来让 CookieHttpSessionIdResolver 和 HeaderHttpSessionIdResolver 自动选择:

```
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.http.MediaType;
import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.session.web.http.CookieHttpSessionIdResolver;
import org.springframework.session.web.http.HeaderHttpSessionIdResolver;
import org.springframework.session.web.http.HttpSessionIdResolver;
import org.springframework.web.accept.ContentNegotiationStrategy;

public class SmartHttpSessionIdResolver implements HttpSessionIdResolver {

protected final HttpSessionIdResolver browser;

protected final HttpSessionIdResolver api;

private final RequestMatcher browserMatcher;

public SmartHttpSessionIdResolver(
ContentNegotiationStrategy contentNegotiationStrategy) {
this.browser = new CookieHttpSessionIdResolver();
this.api = HeaderHttpSessionIdResolver.xAuthToken();

MediaTypeRequestMatcher matcher = new MediaTypeRequestMatcher(
contentNegotiationStrategy, Arrays.asList(MediaType.TEXT_HTML));
matcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL));

RequestHeaderRequestMatcher javascript = new RequestHeaderRequestMatcher(
"X-Requested-With", "XMLHttpRequest");

this.browserMatcher = new OrRequestMatcher(
Arrays.asList(matcher, javascript));
}

/**
* {@inheritDoc}
*/
@Override
public List<String> resolveSessionIds(HttpServletRequest request) {
return getResolver(request).resolveSessionIds(request);
}

/**
* {@inheritDoc}
*/
@Override
public void setSessionId(HttpServletRequest request, HttpServletResponse response, String sessionId) {
getResolver(request).setSessionId(request, response, sessionId);
}

/**
* {@inheritDoc}
*/
@Override
public void expireSession(HttpServletRequest request, HttpServletResponse response) {
getResolver(request).expireSession(request, response);
}

protected HttpSessionIdResolver getResolver(HttpServletRequest request) {
return this.browserMatcher.matches(request) ? this.browser : this.api;
}

}
```
zhenjiachen
2019-12-13 14:53:55 +08:00
@From313 不可能吧,cookie 和 token 都是存在本地,然后请求的时候放在 header 里面啊,没有什么支不支持。把 cookie 当成 token 来用也是一样的。
shazh520
2019-12-13 14:56:48 +08:00
@zhenjiachen 所说的不支持 cookie 应该是没有像浏览器这样方便,需要自己使用代码处理一下
dejavuwind
2019-12-13 15:00:44 +08:00
用过 cookie 和 session,好像还是 cookie 用的多一些
顺便想问问 前后端分离的情况下 前端页面 访问如何做权限管理
meanhow
2019-12-13 15:36:37 +08:00
说道权限,顺道问一问各位数据权限该怎么做
就是员工只能看自己处理的订单,经理可以看所有人的订单这样的
琢磨了半天没什么头绪
VensonEEE
2019-12-13 15:52:36 +08:00
脚手架都集成了 oauth2.0 吧,通用且方便集成,用就完了,熟了也快,少了很多选择的烦恼。
权限,其实没有太好的办法,毕竟很多都是自由配置的。多套 service,自定义注解控制访问权限,避免提权攻击。
jaylee4869
2019-12-13 15:58:52 +08:00
@dejavuwind token,请求头里携带
lihongjie0209
2019-12-13 16:00:13 +08:00
@meanhow #9 这是你的业务逻辑, 还是在业务代码中解决吧
IGJacklove
2019-12-13 16:01:52 +08:00
@dejavuwind 后端做权限不就可以了?是否登录,用户类型,token 加 sql 基本都能解决吧,
shazh520
2019-12-13 16:13:03 +08:00
@meanhow 思路就太多了;接口分开,经理一个,员工一个;一个接口的话判断用户权限,如果是员工的话查询条件加上员工 ID ;。。。
cheng6563
2019-12-13 17:32:31 +08:00
自己造轮子,spring security 真的是一言难尽
a852695
2019-12-13 17:42:44 +08:00
@meanhow 前端所有的权限包括路由都从后端接口获取
ShutTheFu2kUP
2019-12-13 18:34:42 +08:00
@meanhow 订单表加个员工 id,员工只查自己的 od 的订单,经理不带条件
zhazi
2019-12-13 19:52:31 +08:00
spring security 可以支持 thymeleaf 和 restful 的
hantsy
2019-12-13 20:01:01 +08:00
@shazh520 这个是框架安全上设计的考虑,与用不用 Spring Security 没太大关系。

1. 如果 Web (Themleaf)页面 与 API 是一个程序,可以考虑多个 Spring Security Config,用 Order 排序。
如:
@Bean
@Order(0)
httpConfigbean 对应 pathMatcher("/web")使用常规 Web 设置。

@Bean
httpConfigbean 对应 pathMatcher("/api")使用 API 设置,可以无状态也可有状态与前者共享 Session.

2. 如果纯后端 API,直接使用通用 API 安全方案。OAuth2,JWT,SpringSession 等。
客户端( SPA,WebMVC/Themleaf,Mobile APP 等)交互都一样, 用相应的 Http Client 与 API 交互。

从开发维护的角度,第二种比较也容易扩展。
shazh520
2019-12-13 20:41:02 +08:00
@zhazi 都支持,但不同时支持,只能用其一

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/628737

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX