前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringSecurity 入门(二)

SpringSecurity 入门(二)

作者头像
是小张啊喂
发布2021-08-09 17:38:43
2410
发布2021-08-09 17:38:43
举报
文章被收录于专栏:软件软件

上一篇有点水了,这期我们直接上干货,学习认证流程。

先来考虑一下,关于SpringSecurity如何实现的安全权限管理,角色校验,来对比一下权限和角色

代码语言:javascript
复制
// 验证角色 访问 "/product/add" 所应该拥有 admin 的角色
.antMatchers("/product/add").hasRole("admin");
// 访问 "/product/add" 所应该拥有 PRODUCT_ADD 的权限
.antMatchers("/product/add").hasAnyAuthority("PRODUCT_ADD")

SpringSecurity验证当前的用户是否具有这样的角色或者权限,但是这限制于当前的项目需要是前后端同时的情况,我们只需要将当前的权限设置给SpringSecurity,例如:

代码语言:javascript
复制
/**
 * 查询权限并将权限放入 security 中
 *
 * @param http
 * @throws Exception
 */
public void selectPurview(HttpSecurity http) throws Exception {
    List<Purview> purviews = purviewService.selectPurview();
    for (Purview purview : purviews) {
        http.authorizeRequests()
            // 设置权限
            .antMatchers(purview.getUrl()).hasAnyAuthority(purview.getAuthority());
    }
}

如果你想设置成角色,那就将设置权限的代码改成设置角色即可,简单的东西就不上代码了,我们还是抓紧来看下在前后端分离的情况下,怎么处理。

谁开发的,看谁的讲解,直接看 SpringSecurity官方文档第10章文档,第一眼看上去肯定是 SecurityContextHolder,这个类存储经过身份验证的人员的详细信息,讲的真的是很模糊,其实就是登录过后的人员信息。

下面就是SecurityContext,可以从中获取,SecurityContextHolder并包含Authentication当前经过身份验证的用户的信息

代码语言:javascript
复制
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

AuthenticationManager认证管理器就很强, 可以提供用户提供的用于身份验证的凭据,也可以提供来自的当前用户SecurityContext ,已经进行过身份验证的用户,Authentication可以从SecurityContext获取。

Authentication包含:

  • principal-识别用户。使用用户名/密码进行身份验证时,通常是的一个实例UserDetails
  • credentials-通常是密码。在许多情况下,将在验证用户身份后清除此内容,以确保它不会泄漏。
  • authorities-在GrantedAuthoritys是用户被授予高级别权限。角色或范围是几个例子。

这样的话我们可以猜测一下,如果我们将登录成功的用户信息封装成toekn,当他请求接口时通过拦截器,将他的信息进行解析,再传递给 SecurityContextHolder,那是不是就完成了校验。比如这样:

代码语言:javascript
复制
SecurityContextHolder.getContext().setAuthentication(Authentication authentication);

值得思考的是,如何构建这样的一个Authentication authentication对象,回头再去看官方文档10.1,官方文档中提到:

创建一个新Authentication对象。Spring Security并不关心Authentication在上设置了什么类型的实现SecurityContext。在这里我们使用TestingAuthenticationToken它是因为它非常简单。更常见的生产方案是UsernamePasswordAuthenticationToken(userDetails, password, authorities)

UsernamePasswordAuthenticationToken设计用于简单呈现用户名和密码的实现。查看源码:

代码语言:javascript
复制
public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationToken;
public abstract class AbstractAuthenticationToken implements Authentication,CredentialsContainer;

这下就不难明白为什么UsernamePasswordAuthenticationToken可以构建出一个Authentication对象了。

代码语言:javascript
复制
	private final Object principal;
	private Object credentials;

	/**
	 * This constructor should only be used by <code>AuthenticationManager</code> or
	 * <code>AuthenticationProvider</code> implementations that are satisfied with
	 * producing a trusted (i.e. {@link #isAuthenticated()} = <code>true</code>)
	 * authentication token.
	 *
	 * @param principal
	 * @param credentials
	 * @param authorities
	 */
    public UsernamePasswordAuthenticationToken(Object principal, Object credentials,
                Collection<? extends GrantedAuthority> authorities) {
        super(authorities);
        this.principal = principal;
        this.credentials = credentials;
        super.setAuthenticated(true); // must use super, as we override
    }

那就是说实际上,我们应该使用这个构建函数去构建Authentication对象,也就是UsernamePasswordAuthenticationToken(principal, credentials, authorities)

详细解释一下这三个参数

  • principal 显然这个使用final修饰不可以修改,所以传递的值一定是在认证之后不需要修改的,例如:用户信息
  • credentials用于防止认证的信息,可以是token
  • authorities权限集合

思路好像又清晰了,认证的过程是这样的,我们进行登录认证,验证账号密码,生成TOEKN,然后解析当前的TOEKN,获取用户信息,权限集合,用于生成Authentication,放在SecurityContext中,将权限校验和验证都交由SpringSecurity管理,这个思路应该没有什么毛病了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-07-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
多因子身份认证
多因子身份认证(Multi-factor Authentication Service,MFAS)的目的是建立一个多层次的防御体系,通过结合两种或三种认证因子(基于记忆的/基于持有物的/基于生物特征的认证因子)验证访问者的身份,使系统或资源更加安全。攻击者即使破解单一因子(如口令、人脸),应用的安全依然可以得到保障。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档