0
点赞
收藏
分享

微信扫一扫

shiro初体验,蹒跚学步

吃面多放酱 2021-09-21 阅读 6
javaJava web

1-登录登出

  • shiro.ini
[users]
zhangsan=666
lisi=456
  • ShiroTest
@Test
public void testLogin() throws Exception{
    //创建工厂对象,加载配置文件
    IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro.ini");
    //通过工厂对象创建securityManager对象
    SecurityManager securityManager = iniSecurityManagerFactory.getInstance();
    //将securityManager绑定到当前运行环境中,让系统随时随地都可以访问securityManager对象
    SecurityUtils.setSecurityManager(securityManager);
    //创建当前登录的主体(此时主体未认证)
    Subject subject = SecurityUtils.getSubject();
    //收集主体登录的数据(账号密码)
    UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","666");
    //登录操作
    try {
        subject.login(token);
    }catch (Exception e){
        //登录失败
        e.printStackTrace();
    }
    //判断是否登录成功
    System.out.println(subject.isAuthenticated());
    //登出操作
    subject.logout();
    //判断是否登录成功
    System.out.println(subject.isAuthenticated());
}

  • 异常解析
UnknownAccountException====>账号有误
IncorrectCredentialsException====> 密码有误

2-自定义realm

  • 继承AuthorizingRealm,重写三个方法
public class MyRealm extends AuthorizingRealm {
    @Override
    public String getName() {
        return "MyRealm";
    }
    //授权操作
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }
    //认证操作
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //token表示登录时封装的UsernamePasswordToken
        String usernam = (String) token.getPrincipal();
        //假设数据库找不到这个用户名
        if(!usernam.equals("zhangsan")){
            return null;
        }
        String password = "666";
        //simpleAuthenticationInfo表示realm登录比对信息,
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(usernam, password, getName());
        return simpleAuthenticationInfo;
    }
}
  • 配置ini文件,指定使用自定义realm
myRealm= com.wu.realm.MyRealm
securityManager.realms=$myRealm
  • 加载配置文件,执行登录操作
@Test
public void testLoginByRealm() throws Exception{
    //创建工厂对象,加载配置文件
    IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro-realm.ini");
    //通过工厂对象创建securityManager对象
    SecurityManager securityManager = iniSecurityManagerFactory.getInstance();
    //将securityManager绑定到当前运行环境中,让系统随时随地都可以访问securityManager对象
    SecurityUtils.setSecurityManager(securityManager);
    //创建当前登录的主体(此时主体未认证)
    Subject subject = SecurityUtils.getSubject();
    //收集主体登录的数据(账号密码)
    UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","666");
    //登录操作
    try {
        subject.login(token);
    }catch (Exception e){
        e.printStackTrace();
        //登录失败
    }
    //判断是否登录成功
    System.out.println(subject.isAuthenticated());
    //登出操作
    subject.logout();
    //判断是否登录成功
    System.out.println(subject.isAuthenticated());
}

3-加密realm

  • 使用MD5散列
@Test
public void testMD5(){
    //模拟未加密的密码
    String password = "666";
    //使用MD5散列后的结果
    Md5Hash md5Hash = new Md5Hash(password);
    //使用MD5加盐散列后的结果
    md5Hash = new Md5Hash(password,"zhangsan");
    //使用MD5加盐散列3次后的结果
    md5Hash = new Md5Hash(password,"zhangsan",3);
    //输出结果  cd757bae8bd31da92c6b14c235668091
    System.out.println(md5Hash);
}
  • 新建realm,继承AuthorizingRealm,重写三个方法
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
   //token表示登录时封装的UsernamePasswordToken
   String usernam = (String) token.getPrincipal();

   //假设数据库找不到这个用户名
   if(!usernam.equals("zhangsan")){
       return null;
   }
   //模拟数据库中加密之后的密码
   String password = "cd757bae8bd31da92c6b14c235668091";
   //simpleAuthenticationInfo表示realm登录比对信息  ----------加上盐值
   SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(usernam, password, ByteSource.Util.bytes("zhangsan"), getName());
   return simpleAuthenticationInfo;
}
  • 配置ini文件,指定使用自定义realm
[main]
#定义密码凭证器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#设置散列算法
credentialsMatcher.hashAlgorithmName=md5
#设置散列次数
credentialsMatcher.hashIterations=3
#将凭证匹配器设置到realm
myRealm= com.wu.realm.PasswordRealm
myRealm.credentialsMatcher=$credentialsMatcher
securityManager.realms=$myRealm
  • 加载配置文件,执行登录操作
@Test
public void testLoginByPasswordRealm() throws Exception{
    //创建工厂对象,加载配置文件
    IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro-cryptography.ini");
    //通过工厂对象创建securityManager对象
    SecurityManager securityManager = iniSecurityManagerFactory.getInstance();
    //将securityManager绑定到当前运行环境中,让系统随时随地都可以访问securityManager对象
    SecurityUtils.setSecurityManager(securityManager);
    //创建当前登录的主体(此时主体未认证)
    Subject subject = SecurityUtils.getSubject();
    //收集主体登录的数据(账号密码)
    UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","666");
    //登录操作
    try {
        subject.login(token);
    }catch (Exception e){
        e.printStackTrace();
        //登录失败
    }
    //判断是否登录成功
    System.out.println(subject.isAuthenticated());
    //登出操作
    subject.logout();
    //判断是否登录成功
    System.out.println(subject.isAuthenticated());
}

4-权限

  • 继承AuthorizingRealm,重写三个方法
@Override
public String getName() {
    return "SuRealm";
}

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    //获取前端传来的用户名
    String userName = (String) principals.getPrimaryPrincipal();
    //通过用户名去数据库查询其权限(省略------ 。。。。模拟数据)
    Set<String> perms = new HashSet<String>();
    perms.add("user:add");
    perms.add("user:modify");
    perms.add("user:delete");
    //通过用户名去数据库查询其角色(省略------ 。。。。模拟数据)
    Set<String> roles = new HashSet<String>();
    roles.add("administrator");
    roles.add("seller");
    roles.add("buyer");

    SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(roles);
    simpleAuthorizationInfo.setStringPermissions(perms);
    return simpleAuthorizationInfo;
}

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    //token表示登录时封装的UsernamePasswordToken
    String usernam = (String) token.getPrincipal();

    //假设数据库找不到这个用户名
    if(!usernam.equals("zhangsan")){
        return null;
    }
    //模拟数据库中加密之后的密码
    String password = "cd757bae8bd31da92c6b14c235668091";
    //simpleAuthenticationInfo表示realm登录比对信息,
    SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(usernam, password, ByteSource.Util.bytes("zhangsan"), getName());
    return simpleAuthenticationInfo;
}
  • 配置ini文件,指定使用自定义realm
[main]
#定义密码凭证器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#设置散列算法
credentialsMatcher.hashAlgorithmName=md5
#设置散列次数
credentialsMatcher.hashIterations=3
#将凭证匹配器设置到realm
myRealm= com.wu.realm.SuRealm
myRealm.credentialsMatcher=$credentialsMatcher
securityManager.realms=$myRealm
  • 执行登录操作,测试权限

    1,代码实现

    @Test
    public void testLoginByPasswordRealm() throws Exception{
        //创建工厂对象,加载配置文件
        IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro-cryptography-su.ini");
        //通过工厂对象创建securityManager对象
        SecurityManager securityManager = iniSecurityManagerFactory.getInstance();
        //将securityManager绑定到当前运行环境中,让系统随时随地都可以访问securityManager对象
        SecurityUtils.setSecurityManager(securityManager);
        //创建当前登录的主体(此时主体未认证)
        Subject subject = SecurityUtils.getSubject();
        //收集主体登录的数据(账号密码)
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","666");
        //登录操作
        try {
            subject.login(token);
        }catch (Exception e){
            e.printStackTrace();
            //登录失败
        }
        //判断是否登录成功
        System.out.println(subject.isAuthenticated());
    
        //测试权限      需求:输出"hello",需要"user:add"权限
        if(subject.isPermitted("user:add")){
            System.out.println("hello");
        }else {System.out.println("没有权限");}
        //表示一个个判断,返回bool数组
        boolean[] booleans = subject.isPermitted("","","");
        subject.isPermitted(new ArrayList<Permission>());
    
        //测试角色      判断是否具有某个角色
        subject.hasRole("");
        //一个一个判断,是否具有某个角色
        subject.hasRoles(new ArrayList<String>());
        //判断是否具有所有角色
        subject.hasAllRoles(new ArrayList<String>());
    
        //登出操作
        subject.logout();
        //判断是否登录成功
        System.out.println(subject.isAuthenticated());
    }
    

​ 2,注解实现

@RequiresRoles("")
public void test1(){}

待续。。。

举报

相关推荐

0 条评论