Spring Security 4 原理详解

本文详细解析了Spring Security的认证与授权过程。从用户登录到Security Context的构建,阐述了核心组件如Security Context、Authentication、UserDetails、GrantedAuthority的作用。通过配置认证管理器、认证provider和访问控制策略,展示了Spring Security如何判断用户权限。同时,介绍了UsernamePasswordAuthenticationFilter的工作原理,以及如何通过自定义UserDetailsService实现复杂的认证逻辑。
摘要由CSDN通过智能技术生成

场景:

  1. 用户通过提交username和password请求登陆
  2. 服务器验证身份信息是否正确
  3. 获取用户信息(包括角色集合)
  4. 利用3中的信息构建Security Context
  5. 在此之后,该用户的所有请求,Spring Security的访问控制机制将根据Security Context中的信息判断用户是否具有权限

以上,前3点即为认证,构建Security Context,为之后5的授权(访问控制)铺垫,SecurityContext中的用户信息也可供应用程序使用。

Spring Security的几个核心组件

1、SecurityContextHolder
用于存储的Security Context,主要是当前会话的Principal,默认是用ThreadLocal存储这些信息;
常用于获取当前用户的相关信息,Spring Security使用Authentication类来封装这些信息,获取当前会话用户的用户名代码如下所示:

 Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

    if (principal instanceof UserDetails) {
        String username = ((UserDetails)principal).getUsername();
    } else {
        String username = principal.toString();
    }

代码中的getContext()方法的返回值是一个SecurityContext的实例,就是在完成认证之后存储在ThreadLocal中的对象,主要封装了用户的相关信息。

2、UserDetailsPrincipalAuthentication
Spring Security中使用Authentication存储当前用户的主要信息。
Authentication中存储的是Principal,与UserDetails直接可以 强制转换。
UserDetails是Spring Security中的一个核心接口,作用是充当具体业务逻辑中的用户对象与Spring Security中所需要的Principal的适配器。
UserDetails的源码如下所示:

public abstract interface UserDetails extends Serializable {
   
        public abstract Collection<? extends GrantedAuthority> getAuthorities();

        public abstract String getPassword();

        public abstract String getUsername();

        public abstract boolean isAccountNonExpired();

        public abstract boolean isAccountNonLocked();

        public abstract boolean isCredentialsNonExpired();

        public abstract boolean isEnabled();
    }

由源码可知其主要是用户名、密码、权限列表等信息;因此,通常可以在项目定义个自己的用户对象并实现该接口,重写其getAuthorities()方法即可。目的是为了让项目中具体业务逻辑中的权限信息与Spring Security所需的权限配置对应上。举例部分代码,省略getter与setter方法:

    public class UserPo implements UserDetails{
   

        private String userNo;
        private String username;
        private String password;
        private List<RolePo> roles;

        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
            List<RolePo> roles = this.getRoles();
            for(RolePo rp : roles){
                auths.add(new SimpleGrantedAuthority(rp.getRoleName()));
            }
            return auths;
        }
    }

Spring Security提供一个UserDetailsService接口,该接口用于查询并返回一个UserDetails。只要我们实现了该接口,并注入到某

  • 9
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值