黑马程序员技术交流社区

标题: 【武汉校区学习资源】shiro权限管理入门(八) [打印本页]

作者: 武汉分校-小舞    时间: 2017-8-4 17:19
标题: 【武汉校区学习资源】shiro权限管理入门(八)

自定义Realm
[java] viewplain copy print?
[java] viewplain copy print?
packageliuxun.test.shiro.realm;

import java.util.ArrayList;
import java.util.List;

importorg.apache.shiro.authc.AuthenticationException;
importorg.apache.shiro.authc.AuthenticationInfo;
importorg.apache.shiro.authc.AuthenticationToken;
importorg.apache.shiro.authc.SimpleAuthenticationInfo;
importorg.apache.shiro.authc.UsernamePasswordToken;
importorg.apache.shiro.authz.AuthorizationInfo;
importorg.apache.shiro.authz.SimpleAuthorizationInfo;
importorg.apache.shiro.realm.AuthorizingRealm;
importorg.apache.shiro.subject.PrincipalCollection;

public class CustomRealmextends AuthorizingRealm {
// 设置Realm的名称
@Override
public String getName() {
  return "CustomRealm";
}

// 支持UsernamePasswordToken
@Override
public boolean supports(AuthenticationToken token) {
  return token instanceof UsernamePasswordToken;
}

// 用于认证
@Override
protected AuthenticationInfodoGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException{

  // token是用户输入的
  // 第一步从token中取出身份信息
  String usercode = (String) token.getPrincipal();

  // 第二步:根据用户输入的usercode从数据库查询
  // ......

  // 如果查询不到返回null
  // 数据库中用户账号是zhangsan
  if (!usercode.equals("zhangsan")) {
   return null;
  }

  // 模拟从数据库中查询到密码
  String password = "123456";

  // 如果查询到返回认证信息AuthenticationInfo
  SimpleAuthenticationInfo simpleAuthenticationInfo = newSimpleAuthenticationInfo(usercode, password,
    this.getName());

  return simpleAuthenticationInfo;
}

// 用于授权
@Override
protected AuthorizationInfodoGetAuthorizationInfo(PrincipalCollection principals) {

  //从principals获取身份信息
  //将getPrimaryPrincipal方法返回值转为真实类型
  //(在上边的doGetAuthenticationInfo认证通过后填充到SimpleAuthenticationInfo中身份类型)
  String userCode = (String) principals.getPrimaryPrincipal();

  //根据身份信息从数据库中获取权限信息
  //模拟从数据库中取到的数据
  List<String> permissions = new ArrayList<String>();
  permissions.add("user:create");//用户创建
  permissions.add("items:add");//商品添加权限
  //....

  //查询到权限数据,返回授权信息(要包括上边的permissions)
  SimpleAuthorizationInfo simpleAuthorizationInfo = newSimpleAuthorizationInfo();
  //将上边查询到的授权信息填充到simpleAuthorizationInfo对象中
  simpleAuthorizationInfo.addStringPermissions(permissions);

  return simpleAuthorizationInfo;
}
}

CustomRealmMd5.java  
自定义Realm处理散列算法
[java] viewplain copy print?
[hide=d100]
package liuxun.test.shiro.realm;  
  
import org.apache.shiro.authc.AuthenticationException;  
import org.apache.shiro.authc.AuthenticationInfo;  
import org.apache.shiro.authc.AuthenticationToken;  
import org.apache.shiro.authc.SimpleAuthenticationInfo;  
import org.apache.shiro.authc.UsernamePasswordToken;  
import org.apache.shiro.authz.AuthorizationInfo;  
import org.apache.shiro.realm.AuthorizingRealm;  
import org.apache.shiro.subject.PrincipalCollection;  
import org.apache.shiro.util.ByteSource;  
  
public class CustomRealmMd5 extends AuthorizingRealm {  
    // 设置Realm名称  
    @Override  
    public void setName(String name) {  
        super.setName("CustomRealmMd5");  
    }  
  
    // 支持UsernamePasswordToken  
    @Override  
    public boolean supports(AuthenticationToken token) {  
        return token instanceof UsernamePasswordToken;  
    }  
  
    // 用于认证  
    @Override  
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {  
  
        // token保存了用户输入的身份信息userName和password  
        // 第一步:从token中取出身份信息  
        String userCode = (String) token.getPrincipal();  
  
        // 第二步:根据用户输入的userCode从数据库查询  
        // ....  
        // 如果查询不到返回null 假设用户输入的账号是zhansgan  
        // 模拟从数据库中查询账号是zhangsan的用户  
        if (!userCode.equals("zhangsan")) {  
            return null;  
        }  
  
        // 模拟从数据库中查询到密码(散列值)  
        // 按照固定规则加密的结果,此密码是在数据库中存储的,原始密码是123456 盐是qwerty  
        String password = "48474f975022f960bc2afbe49be581e8";  
        // 盐,随机字符串,此随机字符串也是在数据库中存储的,模拟从数据库中获取  
        String salt = "qwerty";  
  
        // 如果查询到则返回认证信息AuthenticationInfo  
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userCode, password,  
                ByteSource.Util.bytes(salt), this.getName());  
         
        return simpleAuthenticationInfo;  
    }  
  
    // 用于授权  
    @Override  
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {  
        return null;  
    }  
  
}  [/hide]
[java] viewplain copy print??
package liuxun.test.shiro.realm;

importorg.apache.shiro.authc.AuthenticationException;
importorg.apache.shiro.authc.AuthenticationInfo;
importorg.apache.shiro.authc.AuthenticationToken;
importorg.apache.shiro.authc.SimpleAuthenticationInfo;
importorg.apache.shiro.authc.UsernamePasswordToken;
importorg.apache.shiro.authz.AuthorizationInfo;
importorg.apache.shiro.realm.AuthorizingRealm;
importorg.apache.shiro.subject.PrincipalCollection;
importorg.apache.shiro.util.ByteSource;

public class CustomRealmMd5extends AuthorizingRealm {
// 设置Realm名称
@Override
public void setName(String name) {
  super.setName("CustomRealmMd5");
}

// 支持UsernamePasswordToken
@Override
public boolean supports(AuthenticationToken token) {
  return token instanceof UsernamePasswordToken;
}

// 用于认证
@Override
protected AuthenticationInfodoGetAuthenticationInfo(AuthenticationToken token) throwsAuthenticationException {

  // token保存了用户输入的身份信息userName和password
  // 第一步:从token中取出身份信息
  String userCode = (String) token.getPrincipal();

  // 第二步:根据用户输入的userCode从数据库查询
  // ....
  // 如果查询不到返回null 假设用户输入的账号是zhansgan
  // 模拟从数据库中查询账号是zhangsan的用户
  if (!userCode.equals("zhangsan")) {
   return null;
  }

  // 模拟从数据库中查询到密码(散列值)
  // 按照固定规则加密的结果,此密码是在数据库中存储的,原始密码是123456 盐是qwerty
  String password = "48474f975022f960bc2afbe49be581e8";
  // 盐,随机字符串,此随机字符串也是在数据库中存储的,模拟从数据库中获取
  String salt = "qwerty";

  // 如果查询到则返回认证信息AuthenticationInfo
  SimpleAuthenticationInfo simpleAuthenticationInfo = newSimpleAuthenticationInfo(userCode, password,
    ByteSource.Util.bytes(salt), this.getName());

  return simpleAuthenticationInfo;
}

// 用于授权
@Override
protected AuthorizationInfodoGetAuthorizationInfo(PrincipalCollection principals) {
  return null;
}

}

log4j.properties
[plain] viewplain copy print?

[plain] view plain copy print?
log4j.rootLogger=debug, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d%p [%c] - %m %n

shiro-first.ini
用于用户身份信息从配置文件中取

[plain] view plain copy print??

[plain] view plain copy print??
#对用户信息进行配置
[users]
#用户账号和密码
zhangsan=123456
lisi=654321

shiro-permission.ini  
用于用户权限和身份信息从配置文件中取
[plain] view plain copy print??

[plain] view plain copy print??
#用户
[users]
#用户zhang的密码是123,此用户具有role1和role2两个角色
zhangsan=123,role1,role2
wang=123,role2

#权限
[roles]
#角色role1对资源user拥有create、update权限
role1=user:create,user:update
#角色role2对资源user拥有create、delete权限
role2=user:create,user:delete
#role3对资源user拥有create权限
role3=user:create

shiro-realm.ini  
用于配置自定义Realm 从数据库中获取身份和权限以及角色信息
[plain] view plain copy print??


[plain] view plain copy print??
[main]
#自定义realm
customRealm=liuxun.test.shiro.realm.CustomRealm
#将realm设置到SecurityManager,相当于Spring中的注入
securityManager.realms=$customRealm

shiro-realm-md5.ini
用于配置自定义Realm 从数据库中获取身份和权限以及角色信息以及散列配置
[plain] view plain copy print??
点击下方标题查看相关学习资料
shiro权限管理入门(一)
shiro权限管理入门(二)
shiro权限管理入门(三)
shiro权限管理入门(四)
shiro权限管理入门(五)
shiro权限管理入门(六)
shiro权限管理入门(七)

作者: silenceandxh    时间: 2017-8-9 14:12
很详细,学习了
作者: Just-Do-It    时间: 2017-8-22 14:36
aaaaaaaaaaaaaaaaaaaa
作者: 邢航    时间: 2017-9-13 16:05
学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习
作者: xgwhsgws    时间: 2017-10-20 21:58
很有用,值得学习,感谢楼主分享




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2