小弟最近刚刚研究 security 整合 jwt 想作为前后端分离的项目的后台
看到网上的文章大概有两种 实现方式
小弟有几个疑问:
JWT
这种属于 security 提供的 httpBasic
还是 formLogin
方式? (网上文章看到使用 formLogin 比较多一些,可能是因为它有自定义登录 URL 的方法。)贴下我最后的配置类吧,我使用的也是第一种方案。因为自己写的过滤器,formLogin,httpBasic,这两个人家封装好的处理方案,我全部禁用了
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomAuthenticationProvider customAuthenticationProvider;
@Autowired
private RedisTemplate redisTemplate;
/**
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.authorizeRequests();
registry.and()
.formLogin().disable()
.authorizeRequests()
.antMatchers("/user/login").permitAll()
.antMatchers("/user/register").permitAll()
.antMatchers("/admin").hasAnyRole("ADMIN")
// 任何请求 需要身份认证
.anyRequest().authenticated()
.and()
// 添加一个过滤 所有访问 /login 的请求给JWTLoginFilter处理 这个类处理所有的JWT相关内容
.addFilterBefore(new JWTLoginFilter("/user/login", HttpMethod.POST.toString(),authenticationManager(),redisTemplate), UsernamePasswordAuthenticationFilter.class)
// 添加一个过滤器,验证其他请求是否合法
.addFilterBefore(new JWTAuthenticationFilter(),UsernamePasswordAuthenticationFilter.class)
// 关闭跨站请求防护
.csrf().disable()
// 前后端分离采用JWT 不需要session
.sessionManagement().disable();
}
/**
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 使用自定义身份验证组件
auth.authenticationProvider(customAuthenticationProvider);
}
@Bean
public Argon2PasswordEncoder passwordEncoder() {
return new Argon2PasswordEncoder();
}
}
1
chenuu 2020-04-30 10:04:33 +08:00
我是用的第一种
|
2
linuxsteam OP @chenuu 也许咱们看的教程一样 哈哈。那你自定义 userDetailsService 了吗
|
3
Oktfolio 2020-04-30 10:47:33 +08:00
/login 不用管,实现自己的 AuthenticationSuccessHandler 。然后 Jwt 鉴权过滤器。当然我自己还实现了一个 json 登录的过滤器。
|
4
chenuu 2020-04-30 11:26:59 +08:00
@linuxsteam 定义了.metadatasource,voter 都有自定义.我这规则略复杂些
|
5
linuxsteam OP @Oktfolio 你实现了这个, 那你用的是 formLogin 方式吧?
|
6
nvkou 2020-04-30 11:50:42 +08:00 via Android
千万别自定义。跟着行规走。不然后面上 sso 不好维护
|
7
hantsy 2020-04-30 12:00:11 +08:00
Authentication 和 Authorization 两个不同的东西。
1,Authentication 解决用户是否合法,可以使用 user/password, fingerprint, qrcode, onetimepassword 等方式。 2, 拿到授权凭证后,比如 token(access_token, id_token), Authorization 是为了判断是否有相应的操作权限。 |
8
EastLord 2020-04-30 12:01:46 +08:00
2
|
9
JRay 2020-04-30 12:14:40 +08:00
我也打算搞这套,准备用第二套方案
|
10
JRay 2020-04-30 12:18:56 +08:00
突然想到要是用 JWT 的话,强制下线这种操作怎么搞呢?这个是无状态的样,要是另外一个地方也保存了 JWT 强制下线就不好搞了
|
13
tang123456 2020-04-30 16:45:07 +08:00
目前我们公司用的是第一种,这两天搭项目我也用的第一种
|
14
linuxsteam OP @JRay 放到 redis 里,我现在写完了,发现跟 spring security 的初衷越来越远了
|
15
linuxsteam OP @tang123456 这种方式去写的话,感觉就用了 security 的令牌以及权限处理,认证几乎是自己写的吧(实现的自己的过滤器)
|
16
securityCoding 2020-04-30 18:40:00 +08:00
1.认证和鉴权是两件事情,第一种是对的
2. @JRay 业务复杂度上来了都会走上 session 这条路 3. 如果在用 spring-cloud 的话 ,我个人推荐还是通过 spring-cloud-gateway 网关自己写 filter 来实现, 把认证和鉴权这种业务无关的行为收拢到网关层面,将复杂度控制在网关层面 ,底层服务聚焦业务即可,只管读相关登录态属性(比如 uid...) |
17
securityCoding 2020-04-30 18:41:30 +08:00
@linuxsteam 哈哈 , 写完发现都是自己的代码,还引入 security 这个复杂的组件...
|
18
luckyrayyy 2020-04-30 18:45:14 +08:00 via iPhone
我是第二种 login 放在 controller 里面。
jwt 用的继承 httpbasic |
19
linuxsteam OP @securityCoding 自己代码还算一般吧,就是比较费劲,如你所说:第一种使用 Security 比较多。
我用的不是 cloud,是自己爱好写的。写完了,感觉有点泄劲哈哈 |
20
Newyorkcity 2020-04-30 21:06:18 +08:00
问下楼主学习 spring security 看什么文档?我看官方文档那么长,读了一两个小时了,我愣是没找到从数据库获取账户密码来进行验证的功能..
|
21
iX8NEGGn 2020-04-30 21:13:25 +08:00 via iPhone
@Newyorkcity 这种是业务,security 不会帮你实现,你要自己实现 UserDetails 接口
|
23
linuxsteam OP @Newyorkcity 如果你想遵守官方得方式,重写 jdbcUserDetails 的方法(service,带不带 service 我忘记了)
|