大佬们,请问您有做过类似 @login
这类拦截登录的封装么?
例如某个 RequestMapping(URL) 方法上,只要加了这个注解,它就自动处理拦截,包括 next 跳转等工作?
不晓得我的表述是否到位,大概的意思应该说了,总而言之:
@login
必须登录才能访问@admin
必须管理员才能访问个人觉得 Spring Security 这类重写 WebSecurityConfigurerAdapter
的方式实在太老土且麻烦。
大佬们请不吝指点一下(秀出您超 man 的肌肉吧)。
因为有点赶时间,如果有现成的最好。。。做伸手党实在不好意思啦。
1
tairan2006 2020-02-01 13:22:43 +08:00 via Android
自己写注解能有多麻烦…
|
2
tangtj 2020-02-01 13:22:59 +08:00
启动后从容器获取`RequestMappingHandlerMapping`,获取所有`HandlerMethod`拿到自己标记了注解的方法.
实现`AccessDecisionVoter`接口,在逻辑内对访问的 url 做判断实现. 把实现配置到`accessDecisionManager()` |
3
k9990009 2020-02-01 14:01:28 +08:00 via Android
自定义注解鉴权,就是启动的时候查找所有 controller,然后找到所有标记了你自定义的注解的 url 及对应所需的角色权限,加个拦截器检查就完了。简单点,你注解也不用写了,就请求 url 加前缀,拦截器根据前缀处理。
|
4
yanyueio OP @k9990009 我理解您的思路大致是:
```java //在 preHandle(HttpServletRequest request) 里面 //拦截器处理用户权限 String uri = request.getRequestURI(); if (uri.startsWith("/admin") && !uri.startsWith("/admin/login")) { //这里先不处理登录后的跳转问题 response.sendRedirect(request.getContextPath() + "/admin/login"); return false; } ``` 然而,这样做的话,SpringSecurity 里面还配置么?即 authroizeReqests() 那套逻辑。 ```java config(HttpSecurity http) { http.authorizeRequests().antMatchers("/admin/**").accsess("hasRole('ADMIN')") .and() .... //blabla } ``` 我这边权鉴还是在 SpringSecurity 逻辑里面,具体说就是 `AuthenticationManagerBuilder`,用的 jdbc auth 那套处理的 user, role,之后配置 config(HttpSecurity http) 这里的时候就发现这样配置 Mapping URL 的逻辑不利于后续扩展,比如后面又增加了其他正则类型的 URL,**写完 Controller 就要过来改这边**。 而自己写拦截器只判断 URL 这一边,那么 SpringSecurity 那套不配置啦?如果配置,那么是不是比原来功夫更多了。 还是感谢您分享自己的经验。 |
5
kanezeng 2020-02-01 16:35:06 +08:00
@yanyueio 我大概记得以前类似这么用拦截器干过,在 preHandle 里去取对应方法的 RequiredPermission 注解,如果有有就判断里面提供的权限。没有再配置 SpringSercurity 了。不过那些都是些小项目,基本上权限管理,登陆验证,token 生成存储与验证之类的都是土法炼钢一整套
|
6
jorneyr 2020-02-01 17:00:07 +08:00
1. 实现自定义注解并在 Spring 中生效,可以参考 https://qtdebug.com/spring-core-aspectj-custom-annotation
2. 在注解中获取当前用户的信息,该判断登录的判断登录,该判断权限的判断权限即可,如果不满足条件,未登录的跳转到登录页面,登录了的权限不够进行提示 |
7
qinxi 2020-02-01 17:54:37 +08:00 1
关键流程:
1. 开启注解拦截 @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled=true) 2. 在 AuthenticationProvider 中给 AuthenticationToken 增加 GrantedAuthority 3.方法或类上增加 @PreAuthorize("hasAuthority(T(com.xxx.enums.Role).ADMIN.name())") 或者通过 HttpSecurity#authorizeRequests 配置 |
8
zhaoyou 2020-02-01 18:18:22 +08:00
自己在拦截器里面控制不香吗?多个拦截器,定义顺序,不同的路径不同的权限。Spring security 对我来说有点重!
|
9
zhang5388137 2020-02-01 18:24:38 +08:00
这个不就是 自定义的拦截器 里面自定义的注解吗
|
10
hantsy 2020-02-01 18:37:45 +08:00
过去多年的经验,Annoations 方式不是很好用。Java EE 规范中是这样为主。
对于 Http 访问,URI 拦截才是最简单的,集中配置更简单。 Spring Security 支持三种 Annotations。 1. Secured 2. PreAuthorize, PostAuthorize 3. Java EE 兼容 Annotations 从系统设计的角度,定义一个自己的 Adapter 集中处理安全配置。 1. 将 Security 配置从业务代码分离出来,也是一种解耦吧。 2. 可以使用编程方式配置,也就是说安全属性可以写到数据库或者其它地方,并且可以动态配置(中国人不是喜欢界面配置权限,这种方式很容易实现)。 3. 更容易写测试,测试逻辑时完全可以将安全配置 Disable 掉(如果你写测试的话)。 |
11
yanyueio OP |
12
hantsy 2020-02-01 19:26:19 +08:00
@qinxi
1. 第一步中,如果是使用最新 Spring Boot,不要添加 @EnableWebSecurity,Spring Boot AutoConfiguration 会对添加默认 Spring Security 配置。 1. 添加 @EnableWebSecurity 会破坏默认配置。 2. 而一个普通 @Configuration WebSecurityConfigurerAdapter bean 会在默认配置基础上添加自己的配置。 类似在 Spring Boot 中,@EnableWebMVC, @Enable***repsitories 都不要使用。配置自己项目时,参阅 SpringBoot 文档,大部分默认配置可以通过修改 applicaiton.properties|yaml 简单的完成。 2. 最简单的实现,只需要配置一个 UserDetailsService Bean。除非你想改变 Anthentication 内部机制,才需要自己的 AnthenticationProvider。 |
13
qinxi 2020-02-01 23:01:38 +08:00
@hantsy #12 因为我使用到自定义以及多种认证方式结合的登录,所以我的 filter,provider,token,handle 都是自己实现的.
就算是使用默认实现,也是同样的流程.区别在于谁实现的问题 |
14
abcbuzhiming 2020-02-02 11:48:25 +08:00
Spring security 实现的非常学术化,很多地方很死板,尤其是对登录处理器的配置,一点都不如 shiro 灵活,我不建议用这个库,甚至 spring 自己的社区用的都是 shiro
|
15
hantsy 2020-02-02 12:32:25 +08:00
@abcbuzhiming 当你要支持各种协议的时候,你就发现 Shiro 多少简陋。
|
16
hantsy 2020-02-02 12:44:30 +08:00
@qinxi Spring Security 5 内部支持 Http Basic, Spring Session (一种 Token 机制),X509 安全证书, user/password login form, 和 OAuth2/OIDC 协议,这个衍生的子协议太多了,内部支持一些实现,包括 twitter,facebook, google, okta, github 等,其它的 Oauth2/Oidc 兼容协议一样可以配置(复杂一点)。
对于多种安全配置,我倾向于使用成熟方案,比如 Keycloak,还有 Cloud 服务,比如 Okta,Auth0. 可以轻松配置集成多种登录一起,比如 2fa, otp, 普通的 user/password , social ( OAuth2 ) 等,这些服务都可以很好与 Spring Security 5 集成。 |