权限管理与Shiro入门(十一)

2023-10-07 10:15:08 浏览数 (1)

4.4.3 自定义Realm

Realm域:Shiro从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源

(1)自定义Realm

代码语言:javascript复制
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import java.util.ArrayList;
import java.util.List;
/**
* 自定义realm,需要继承AuthorizingRealm父类
*     重写父类中的两个方法
*         doGetAuthorizationInfo     :授权
*         doGetAuthenticationInfo     :认证
*/
public class PermissionRealm extends AuthorizingRealm {
    @Override
    public void setName(String name) {
        super.setName("permissionRealm");
   }
    /**
     * 授权:授权的主要目的就是查询数据库获取用户的所有角色和权限信息
     */
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection
principalCollection) {
        // 1.从principals获取已认证用户的信息
        String username = (String) principalCollection.getPrimaryPrincipal();
        /**
         * 正式系统:应该从数据库中根据用户名或者id查询
         *         这里为了方便演示,手动构造
         */
        // 2.模拟从数据库中查询的用户所有权限
        List<String> permissions = new ArrayList<String>();
        permissions.add("user:save");// 用户的创建
        permissions.add("user:update");// 商品添加权限 
          // 3.模拟从数据库中查询的用户所有角色
        List<String> roles = new ArrayList<String>();
        roles.add("role1");
        roles.add("role2");
        // 4.构造权限数据
        SimpleAuthorizationInfo simpleAuthorizationInfo = new
SimpleAuthorizationInfo();
        // 5.将查询的权限数据保存到simpleAuthorizationInfo
        simpleAuthorizationInfo.addStringPermissions(permissions);
        // 6.将查询的角色数据保存到simpleAuthorizationInfo
        simpleAuthorizationInfo.addRoles(roles);
        return simpleAuthorizationInfo;
   }
    /**
     * 认证:认证的主要目的,比较用户输入的用户名密码是否和数据库中的一致
     */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken
authenticationToken) throws AuthenticationException {
        //1.获取登录的upToken
        UsernamePasswordToken upToken = (UsernamePasswordToken)authenticationToken;
        //2.获取输入的用户名密码
        String username = upToken.getUsername();
        String password = new String(upToken.getPassword());
        /**
         * 3.验证用户名密码是否正确
         * 正式系统:应该从数据库中查询用户并比较密码是否一致
         *         为了测试,只要输入的密码为123456则登录成功
         */
        if(!password.equals("123456")) {
            throw  new RuntimeException("用户名或密码错误");//抛出异常表示认证失败
       }else{
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, 
password,
                    this.getName());
            return info;
       }
   }
}

(2)配置shiro的ini配置文件(shiro-realm.ini)

代码语言:javascript复制
[main]
#声明realm
permReam=cn.itcast.shiro.PermissionRealm
#注册realm到securityManager中
securityManager.realms=$permReam

(3)验证

代码语言:javascript复制
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.junit.Before;
import org.junit.Test;
public class ShiroTest2 {
    private SecurityManager securityManager;
    @Before
    public void init() throws Exception{
        //1.加载ini配置文件创建SecurityManager
        Factory<SecurityManager> factory = new
IniSecurityManagerFactory("classpath:shiro-realm.ini");
        //2.获取securityManager
        SecurityManager securityManager = factory.getInstance();
        //13.将securityManager绑定到当前运行环境
        SecurityUtils.setSecurityManager(securityManager);
   }
    @Test
    public void testLogin() throws Exception{
        //1.创建主体(此时的主体还为经过认证)
        Subject subject = SecurityUtils.getSubject();
        //2.构造主体登录的凭证(即用户名/密码)
        UsernamePasswordToken upToken = new UsernamePasswordToken("lisi","123456");
        //3.主体登录
        subject.login(upToken);
        //登录成功验证是否具有role1角色
        //System.out.println("当前用户具有role1=" subject.hasRole("role3"));
        //登录成功验证是否具有某些权限
        System.out.println("当前用户具有user:save权限=" subject.isPermitted("user:save"));
   }
}

0 人点赞