赞
踩
subject主题,外部应用与subject进行交互,subject将用户作为当前操作的主体,这个主体:可以是一个 通过浏览器请求的用户,也可能是一个运行的程序。subject在shiro中是一个接口,接口中定义了很多认证授权的方法,外部程序通过subject进行认证授权,而subject是通过SecurityManager安全管理器进行认证鉴权。
securitymanager权限管理器,它是shiro的核心,负责对所有的subject进行安全管理。通过securityManager可以完成subject的认证、授权等,SecurityManager是通过Authentication进行认证,通过Authorizer进行授权,通过SessionManager进行会话管理等。SecurityManager是一个接口,继承了Authentication,Authorizer,SessionManager这三个接口。
Authenticator即认证器,对用户登录时进行身份认证。
Authorizer授权器,用户通过认证器认证通过,在访问功能时需要授权器判断用户是否有此功能的操作权限。
Realm领域,相当于datasource数据源,securityManager进行安全认证需要通过Realm获取用户权限数据。
比如:如果用户身份数据在数据库那么realm就需要从数据库获取用户身份信息。
注意:不要把realm理解从只是从数据源获取数据,在realm中还有认证授权校验的相关的代码。
SessionManager会话管理,shiro框架定义了一套绘画管理,它不依赖web容器的session,所以shiro可以使用在非web应用上,也可以将分布式应用的会话集中在一点管理,此特性可使它实现单点登录。
SessionDAO即会话dao,是对session会话操作的一套接口
比如:可以通过jdbc将会话存储到数据库,也可以把session存储到缓存服务器。
CacheManager缓存管理,将用户权限数据存储在缓存,这样可以提高性能。
Cryptography密码管理,shiro提供了一套加密/解密的组件,方便开发。比如提供常用的散列、加/解密等功能。
用户登录信息令牌,这个对象中封装了用户的登录信息,主要包括用户名和密码,在登录的时候会创建这个令牌。
Spring 安全性是提供认证、授权和防范常见攻击的框架。由于对imperative和reactive应用程序的安全都提供了第一类支持,因此它是保护基于 Spring 的应用程序的事实上的标准。
SecurityContextHolder它持有的是安全上下文(SecurityContext)的信息。当前操作的用户是谁,谁用户是否已经被认证,他拥有那些角色权等等,这些都被保存在SecurityContextHolder中。SecurityContextHolder默认使用ThreadLocal策略来存储认证信息。看到ThreadLocal也就意味着,这是一种与线程绑定的策略。在web环境下,springsecurity在用户登录时自动绑定认证信息到当前线程,在用户退出时,自动清除当前线程的认证信息。
安全上下文,主要持有Authentication对象,如果用户未鉴权,那么Authentication对象将会空的。该示例可以通过SecurityContextHolder.getContext静态方法获取。
鉴权对象,该对象注意包含了用户的详细信息(UserDetails)和用户鉴权时所需要的信息,如用户提价奥的用户密码、Remember-me Token,或者digestHash值等,按不同鉴权方式使用不同的Authentication实现。
Authentication是spring security包中的接口,直接继承自Principal类,而Principal是位于java.security包中的。可以见得,Authentication在spring security中是最高级别的身份/认证的抽象。由这个顶级接口,我们可以得到用户拥有的权限信息列表,密码,用户细节信息,用户身份信息,认证信息。
该接口表示了当前用户所有的权限(或者角色)信息。这些信息有授权负责对象AccessDecisionManager来使用,并觉得最终用户是否可以访问某资源。(URL或方法调用或域对象)。鉴权时并不会使用到该对象。
这个接口规范了用户详细信息所拥有的字段,譬如用户名、密码、账号是否过期、是否锁定等。在SpringSecurity中,获取当前登录的用户的信息,一般情况时需要在这个接口上面进行扩展,用来对接自己系统的用户。
这个接口只提供一个接口loadUserByUsername(String username),这个接口非常重要,一般情况下我们都是通过扩展这个接口来显示获取我们的用户信息,用户登录时传递的用户名和密码也是通过这里查找出来的用户名和密码进行校验但是真正的校验不在这里,而是由AuthenticationManager以及AuthenticationProvider负责的,需要强调的是,如果用户不存在,不应返回NULL,而要抛出异常UsernameNotFoundException。
AuthenticationManager(接口)是认证相关的核心接口,也是发起认证的出发点,因为在实际需求中,我们可能会允许用户使用用户名+密码登录,同时允许用户使用邮箱+密码,手机号码+密码登录,甚至,可能允许用户使用指纹登录(还有这样的操作?没想到吧),所以说AuthenticationManager一般不直接认证,AuthenticationManager接口的常用实现类ProviderManager 内部会维护一个List<AuthenticationProvider>列表,存放多种认证方式,实际上这是委托者模式的应用(Delegate)。也就是说,核心的认证入口始终只有一个:AuthenticationManager,不同的认证方式:用户名+密码(UsernamePasswordAuthenticationToken),邮箱+密码,手机号码+密码登录则对应了三个AuthenticationProvider。其中有一个重要的实现类是ProviderManager
AuthenticationProvider最最最常用的一个实现便是DaoAuthenticationProvider。顾名思义,Dao正是数据访问层的缩写,也暗示了这个身份认证器的实现思路。主要作用:它获取用户提交的用户名和密码,比对其正确性,如果正确,返回一个数据库中的用户信息(假设用户信息被保存在数据库中)。
- @Configuration
- public class SecurityConfig extends WebSecurityConfigurerAdapter {
- @Bean
- public UserDetailsService userDetailsService() {
- InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
- manager.createUser(User.withUsername("xls").password("123").authorities("p1").build());
- manager.createUser(User.withUsername("wxl").password("456").authorities("p2").build());
- return manager;
- }
- @Bean
- public PasswordEncoder passwordEncoder(){
- return new BCryptPasswordEncoder();
- } //注解密码加密方式
-
- protected void configure(HttpSecurity http) throws Exception {
- http.csrf().disable()
- .authorizeRequests() //所有请求
- .antMatchers("/r/r1").hasAuthority("p1") //访问r1需要p1权限
- .antMatchers("/r/r2").hasAuthority("p2") //访问r2需要p2权限
- .antMatchers("/r/**").authenticated() //所有/r/**的请求必须认正通过
- .anyRequest().permitAll()//除了/r/**,其他的请求可以访问
- .and()
- .formLogin() //运行表单登录
- .loginPage("/loginpage")//登录页面访问地址(可以省略)
- .loginProcessingUrl("/doLogin") //登录的提交接口 从根目录开始
- .successForwardUrl("/login-success"); //自定义登录成功的页面地址
-
-
- }
- }
- @Service
- public class SpringbootUserDetialService implements UserDetailsService {
- @Autowired(required = false)
- private UserMapper mapper;
- @Autowired(required = false)
- private RoleMapper roleMapper;
- @Override
- public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
-
- com.apesource.springboot_security.doman.User one = mapper.findUserAll(username);
- if (one==null){ //查询用户信息
- return null;
- }
- //放入权限信息
- String[] rs=new String[one.getRoles().get(0).getPerms().size()];
- Role role = one.getRoles().get(0);
- List<Permission> ps = role.getPerms();
- for (int i = 0; i < ps.size(); i++) {
- rs[i]=ps.get(i).getCode();
- }
- UserDetails user = User.withUsername(one.getUsername()).password(one.getPassword()).authorities(rs).build();
- return user;
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。