shiro认证与授权

  参考链接:Shiro入门教程

1.shiro认证

                    1.1 shiro认证流程 

                              

·       1.2. shiro认证入门程序。

              新建 shiro-first.ini通过此配置文件创建securityManager工厂。

#对用户信息进行配置,未自定义义Realm
[users]
#用户账号和密码
zhangsan=111111
lisi=222222


[main]
#定义凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#散列算法
credentialsMatcher.hashAlgorithmName=md5
#散列次数
credentialsMatcher.hashIterations=2
#自定义realm,如果自定义了Realm,[users]会失效
customerRealm=com.lx.Shiro.CustomRealm
#将凭证匹配器设置到realm
customerRealm.credentialsMatcher=$credentialsMatcher
#将realm设置到securityManager,相当于spring注入额
securityManager.realms=$customerRealm

1.3.提交认证

 public void iniTest() throws UnsupportedEncodingException {
        URL url = MyShiroTest.class.getResource("../../../../resources/shiro-first.ini");
        String s = url.toString().replaceAll("%20", " ");
        String decode = URLDecoder.decode(s, "utf-8");

        IniSecurityManagerFactory securityManagerFactory = new IniSecurityManagerFactory(decode);
        SecurityUtils.setSecurityManager(securityManagerFactory.getInstance());
        //从SecurityUtils里边创建一个subject
        Subject subject = SecurityUtils.getSubject();
        //在认证提交前准备token(令牌)
        UsernamePasswordToken token = new UsernamePasswordToken("lisi_md5", "111111");
        try {
            //执行认证提交
            subject.login(token);
        } catch (AuthenticationException e) {
            System.out.println(e);
        }
        //是否认证通过
        boolean isAuthenticated = subject.isAuthenticated();
        System.out.println("是否认证通过:" + isAuthenticated);
}

2.shiro授权

   2.1授权流程

                   

2.2授权方式

shiro支持三种方式的授权:
- 编程式:通过写if/else授权代码块完成:

Subject  subject = SecurityUtils.getSubject();
if(subject.hasRole("admin")){
  //有权限
}else{
   //无权限
}
  • 注解方式:通过在执行的java 方法上放置相应的注解完成;
@RequiresRoles("admin")
public void hello(){
  //有权限
}
  • jsp标签: 在jsp页面通过相应的标签完成:
<shiro:hasRole name="admin">
<!-- 有权限 -->
</shiro:hasRole>

2.3 新建 shiro-permission.ini

创建存放权限的配置文件shiro-permission.ini,里面的内容相当于在数据库里面

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

#如果自定了Realm[roles]会失效
[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

 2.4 权限测试

@Test
    public void iniTest() throws UnsupportedEncodingException {
        URL url = MyShiroTest.class.getResource("../../../../resources/shiro-first.ini");
        String s = url.toString().replaceAll("%20", " ");
        String decode = URLDecoder.decode(s, "utf-8");

        IniSecurityManagerFactory securityManagerFactory = new IniSecurityManagerFactory(decode);
        SecurityUtils.setSecurityManager(securityManagerFactory.getInstance());
        //从SecurityUtils里边创建一个subject
        Subject subject = SecurityUtils.getSubject();
        //在认证提交前准备token(令牌)
        UsernamePasswordToken token = new UsernamePasswordToken("lisi_md5", "111111");
        try {
            //执行认证提交
            subject.login(token);
        } catch (AuthenticationException e) {
            System.out.println(e);
        }
        //是否认证通过
        boolean isAuthenticated = subject.isAuthenticated();
        System.out.println("是否认证通过:" + isAuthenticated);

        // 是否有某一个角色
        System.out.println("用户是否拥有一个角色:" + subject.hasRole("role1"));
        // 是否有多个角色
        System.out.println("用户是否拥有多个角色:" + subject.hasAllRoles(Arrays.asList("role1", "role2")));

        // 基于资源授权
        System.out.println("是否拥有某一个权限:" + subject.isPermitted("user:delete"));
        System.out.println("是否拥有多个权限:" + subject.isPermittedAll("user:create:1",    "user:delete"));

        //退出操作
        subject.logout();
    }

自定义的Relam

public class CustomRealm extends AuthorizingRealm {
    static Map<String, String> userPassMap = new HashMap<>();

    static {
        userPassMap.put("lisi", "111111");
        userPassMap.put("lisi_md5", "36f2dfa24d0a9fa97276abbe13e596fc_qwerty");
    }

    /**
     * 授权
     *
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 获取身份信息
        String username = (String) principals.getPrimaryPrincipal();
        // 根据身份信息从数据库中查询权限数据
        //....这里使用静态数据模拟
        List<String> permissions = new ArrayList<String>();
        permissions.add("user:create");
        permissions.add("user:delete");

        //将权限信息封闭为AuthorizationInfo

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        // 模拟数据库查询角色信息
        Set<String> roles = new HashSet<>();
        roles.add("role1");
        simpleAuthorizationInfo.setRoles(roles);
        for(String permission:permissions){
            simpleAuthorizationInfo.addStringPermission(permission);
        }

        return simpleAuthorizationInfo;
    }

    /**
     * 认证
     *
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // token是用户输入的
        // 第一步从token中取出身份信息
        String userCode = (String) token.getPrincipal();
        // 模拟从数据库查询到密码
        if (!userPassMap.containsKey(userCode)) {
            return null;
        }
        SimpleAuthenticationInfo simpleAuthenticationInfo = null;
        String password = userPassMap.get(userCode);
        if (password.contains("_")) {
            // 模拟从数据库查询到密码,散列值
            String pw = password.split("_")[0];
            // 从数据库获取salt
            String salt = password.split("_")[1];
            simpleAuthenticationInfo = new SimpleAuthenticationInfo(userCode, pw, ByteSource.Util.bytes(salt), getName());
        } else {
            simpleAuthenticationInfo = new SimpleAuthenticationInfo(userCode, password, getName());
        }
        return simpleAuthenticationInfo;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值