Shiro之温故而知新

文章目录

  • 认证中抽象出来的对象
    • Subject:主体
    • Principal:身份信息
    • Credential:凭证信息
  • 授权中抽象出来的对象
    • Who,即主体(Subject)
    • What,即资源(Resource)
    • How,权限/许可(Permission)
  • shiro架构图
  • 权限模型
  • shiro的授权
  • web页面shiro标签
  • 认证和授权流程图
  • SpringBoot整合Shiro

Shiro分为认证和授权
Shiro之温故而知新_第1张图片

认证中抽象出来的对象

Subject:主体

访问系统的用户,主体可以是用户,程序等。进行认证的都成为主体。

Principal:身份信息

是主体(subject)进行身份认证的标识,标识必须具有唯一性,如用户名、手机号、邮箱地址等,一个主体可以
有多个身份,但是必须有一个主身份(Primary Principal),比如手机号登录,或者账户登录。

Credential:凭证信息

是只有主体自己知道的安全信息,如密码、证书等。

授权中抽象出来的对象

授权可简单理解为who对what(which)进行How操作:

Who,即主体(Subject)

主体需要访问系统中的资源。

What,即资源(Resource)

如系统菜单、页面、按钮、类方法、系统商品信息等。资源包括资源类型和资源实例,比如商品信息为资源类型,类型为t01的商品为资源实例,编号为001的商品信息也属于资源实例。

How,权限/许可(Permission)

规定了主体对资源的操作许可,权限离开资源没有意义,如用户查询权限、用户添加权限、某个类方法的调用权限、编号为001用户的修改权限等,通过权限可知主体对哪些资源都有哪些操作
许可。

权限分为粗颗粒和细颗粒,粗颗粒权限是指对资源类型的权限,细颗粒权限是对资源实例的权限

shiro架构图

Shiro之温故而知新_第2张图片

权限模型

Shiro之温故而知新_第3张图片

shiro的授权

subject.isAuthenticated()							//登录是否成功
subject.hasRole("admin")							//验证是否有admin角色
subject.hasAllRoles(Arrays.asList("admin","super"))		//验证是否包含所有角色
subject.hasRoles(Arrays.asList("admin","super"))		//验证是否有某一个角色
subject.isAuthenticated()							//验证是否登录成功
subject.isPermitted("user:delete")					//验证用户是否有该权限

web页面shiro标签

<shiro:authenticated></shiro:authenticated>			//已经认证
<shiro:notAuthenticated></shiro:notAuthenticated>	//未认证
<shiro:principal></shiro:principal>					//获取主身份信息

<shiro:hasRole name="admin"></shiro:hasRole>						//判断是否有该角色
<shiro:hasAnyRoles name="admin,super"></shiro:hasAnyRoles>		//判断是否有某一个角色(有一个就可执行)

<shiro:hasPermission name="banner:delete"></shiro:hasPermission>		//判断是否有该权限

认证和授权流程图

Shiro之温故而知新_第4张图片

SpringBoot整合Shiro

引入依赖

 <dependency>
     <groupId>org.apache.shiro</groupId>
     <artifactId>shiro-spring-boot-web-starter</artifactId>
     <version>1.4.1</version>
 </dependency>

Shiro之温故而知新_第5张图片
创建shiro过滤器

package cn.czboy.shiro;

import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;

@Configuration
public class ShiroFilter {

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        System.out.println("===========shiroFilter");
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        HashMap<String,String> map = new HashMap<>();
        map.put("/subject/**","anon");
        map.put("/login.jsp","anon");
        map.put("/index.jsp","anon");
        map.put("/**","authc");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        shiroFilterFactoryBean.setLoginUrl("/login.jsp");//设置拦截后跳转的网页
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        return shiroFilterFactoryBean;
    }

    @Bean
    public DefaultWebSecurityManager securityManager(MyRealm myRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        MemoryConstrainedCacheManager cache = new MemoryConstrainedCacheManager();
        securityManager.setCacheManager(cache);
        securityManager.setRealm(myRealm);
        return securityManager;
    }

    @Bean
    public MyRealm myRealm() {
        MyRealm myRealm = new MyRealm();
        return myRealm;
    }
}

创建自定义Realm

package cn.czboy.shiro;

import cn.czboy.entity.Role;
import cn.czboy.entity.Subject;
import cn.czboy.mapper.SubjectDao;
import cn.czboy.utils.SpringContextUtil;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

public class MyRealm extends AuthorizingRealm {


    /**授权*/
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = (String)principalCollection.getPrimaryPrincipal();
        SubjectDao subjectDao = (SubjectDao)SpringContextUtil.getBean(SubjectDao.class);
        //根据主体获取角色
        List<Role> roles = subjectDao.findByRole(username);
		
       	HashSet<String> set = new HashSet<>();
        ArrayList<String> arrayList = new ArrayList<>();
       
        SimpleAuthorizationInfo authorizationInfo = null;
        if(primaryPrincipal.equals(admin.getUsername())){
            authorizationInfo = new SimpleAuthorizationInfo();

            for(RoleDto role:roles){
                arrayList.add(role.getRoleName());
                String id = role.getId();
                //根据角色查权限
                List<String> permissionss = adminService.findByPermission(id);
                for(String key:permissionss){
                    set.add(key);
                }
            }

            authorizationInfo.addStringPermissions(set);//权限赋值
            authorizationInfo.addRoles(arrayList);//角色赋值
        }

        return authorizationInfo;
    }

    /**认证*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username = (String)authenticationToken.getPrincipal();
        String password = new String((char[]) authenticationToken.getCredentials());
        SubjectDao subjectDao = (SubjectDao)SpringContextUtil.getBean(SubjectDao.class);
        Subject subject = subjectDao.findByUserName(username);
        AuthenticationInfo authenticationInfo = null;
        if (subject == null) {
            throw new UnknownAccountException("账户不存在!");
        }
        if (!subject.getUsername().equals(username)) {
            throw new UnknownAccountException("用户名错误!");
        }
        if (!subject.getPassword().equals(password)) {
            throw new IncorrectCredentialsException("密码错误!");
        }
        authenticationInfo  = new SimpleAuthenticationInfo(subject.getUsername(), subject.getPassword(), this.getName());
        System.out.println("================="+subject);
        return authenticationInfo;
    }
}

SubjectController

package cn.czboy.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/subject")
public class SubjectController {

    /**用户登陆*/
    @RequestMapping("/login")
    public String login(String username,String password) {
        System.out.println("========="+username);
        System.out.println("========="+password);
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            subject.login(token);
            return "yes";
        } catch (UnknownAccountException e) {
            System.out.println(e.getMessage());
            return "no";
        } catch (IncorrectCredentialsException e) {
            System.out.println(e.getMessage());
            return "no";
        }
    }
}

你可能感兴趣的:(java)