shiro安全框架详解

shiro详解

shiro:Apache Shiro 是Java 的一个安全框架。Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE 环境,也可以用在JavaEE 环境。Shiro 可以帮助我们完成:认证【登陆】、授权【权限】、加密【密码】、会话管理、与Web 集成、缓存等。
shiro执行流程:在这里插入图片描述
subject: 理解为用户;
securityManager: 安全管理 它是核心组件。
Authenticator: 认证器
Authorizer: 授权器。
Realm: 理解为和数据库交互的一个组件。

快速入门

1,引入依赖:shiro-core
2. 创建一个ini文件用来表示数据库
	[users]===表示user表
	zs=123456
	ls=123456
3. 测试
package com.ykq.ini;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;

/**
 * @Author 呆鸡
 * @Date 2021/4/1 14:42
 * @Version 1.0
 */
public class Test {
    public static void main(String[] args) {
        //得到SecurityManager对象
        DefaultSecurityManager securityManager=new DefaultSecurityManager();
        //设置securityManager管理的realm对象
        securityManager.setRealm(new IniRealm("classpath:shiro.ini"));
         //3.把securityManager绑定到SecurityUtils
        SecurityUtils.setSecurityManager(securityManager);
        //4. 获取Subject对象
        Subject subject = SecurityUtils.getSubject();
        //封装账户和密码
        UsernamePasswordToken token=new UsernamePasswordToken("zs","123456");
       try {
           //5.执行认证功能
           subject.login(token);//token:
           System.out.println("账户和密码正确");
       }catch (Exception e){
           e.printStackTrace();
           System.out.println("账户或密码错误");
       }
        //isAuthenticated()判断当前的用户是否被认证
        System.out.println("是否认证成功:"+subject.isAuthenticated());
       //退出登陆
         subject.logout();
        //isAuthenticated()判断当前的用户是否被认证
        System.out.println("是否认证成功:"+subject.isAuthenticated());

    }
}

认证流程在这里插入图片描述

  1. 首先调用 Subject.login(token) 进行登录,其会自动委托给 Security Manager,调用之前必须通过
  2. SecurityUtils.setSecurityManager() 设置;
  3. SecurityManager 负责真正的身份验证逻辑;它会委托给 Authenticator 进行身份验证;
  4. Authenticator 才是真正的身份验证者,Shiro API 中核心的身份认证入口点,此处可以自定义插入自己的实现;
  5. Authenticator 可能会委托给相应的 AuthenticationStrategy 进行多 Realm 身份验证,默认 ModularRealmAuthenticator 会调用 AuthenticationStrategy 进行多 Realm 身份验证;
  6. Authenticator 会把相应的 token 传入 Realm,从 Realm 获取身份验证信息,如果没有返回 / 抛出异常表示身份验证失败了。
  7. 此处可以配置多个 Realm,将按照相应的顺序及策略进行访问。

正常开发中连接的是数据库,我们需要定义自己的realm类

  1. 创建自己的realm类
  2. 继承AuthorizingRealm
package com.ykq.myrealm;

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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.List;

/**
 * @Author 闫克起
 * @Date 2021/4/1 16:04
 * @Version 1.0
 */
public class MyRealm extends AuthorizingRealm {

    private UserService userService=new UserService();
    //当执行授权时调用该方法。
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        User user = (User) principals.getPrimaryPrincipal();
        System.out.println("授权方法的执行~~~~~~~~~~~~~~~~~~~~~~~"+user);
        //根据用户id查询该用户具有的权限码
        List<String> permissions=userService.findPermissionByUserId(user.getId());

        //绑定权限
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        info.addStringPermissions(permissions);
        return info;
    }

    //当执行认证功能时调用该方法
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("认证方法的执行~~~~~~~~~~~~~~~~~~~~~~~");
        String loginname=token.getPrincipal().toString();//得到账户 唯一的标识。
        //调用service中方法  根据用户名查询用户信息。
        User user=userService.findByLoginname(loginname);
        if(user!=null){
            //Object principal, 账号 可以被登陆成功后获取 还可以传给授权的方法
            // Object credentials, 从数据库中查询的密码
            // String realmName:当前realm的名称
            SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(user,user.getPassword(),this.getName());
            return info;
        }
        return null;
    }
}

shiro的密码加密

MD5加密:非对称加密

public static void main(String[] args) {
        //Md5Hash md5Hash=new Md5Hash("123456");//把明文123456 转化为密文
        //System.out.println(md5Hash.toString());//e10adc3949ba59abbe56e057f20f883e 网上的把密文和明文记录起来了。

        //把明文+盐 再进行加密---密文
       // Md5Hash md5Hash=new Md5Hash("123456","xjp?");//123456ykq?
       // System.out.println(md5Hash.toString());

        //把明文+盐 再进行加密---密文---->再经过1024次散列【1024加密】
        Md5Hash md5Hash=new Md5Hash("123456","xjp?",1024);
        System.out.println(md5Hash.toString());

    }

改进自己的realm类

//当执行认证功能时调用该方法
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("认证方法的执行~~~~~~~~~~~~~~~~~~~~~~~");
        String loginname=token.getPrincipal().toString();//得到账户 唯一的标识。
        //调用service中方法  根据用户名查询用户信息。
        User user=userService.findByLoginname(loginname);
        if(user!=null){
            //Object principal, 账号 可以被登陆成功后获取 还可以传给授权的方法
            // Object credentials, 从数据库中查询的密码
            // String realmName:当前realm的名称
            ByteSource salt = ByteSource.Util.bytes("xjp?");//得到盐

            SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(user,user.getPassword(),salt,this.getName());
            return info;
        }
        return null;
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值