• shiro安全框架


    shiro的作用
    shiro是一个安全框架。主要可以帮助我们解决程序开发中认证和授权的问题。上次做的权限系统,权限控制的粒度到模块级别了,如果只要能看到操作的菜单,就能操作菜单下所有的功能。以后这种权限设计模式,可能不太好满足什么的需求的需要?以后项目中,有坑你权限粒度控制的更细,有可能要控制到模块下的按钮级别,更有甚者,控制到数据的级别。以后为了方便各种各样的常用的权限管理需求的实现。我们有必要使用了比较好的安全框架。早期的Spring Security作为一个比较完善的安全框架比较火,但是spring security学习成本比较高。之后又出现了一个shiro的安全框架,学习成本降低了很多。而且基本的功能也比较完善。shiro也提供很多其他的功能:
    shiro的架构
      Subject:主题 被验证的对象,一般指的当前用户对象。但是不仅仅可以指当前用户对象,还可以是是其他东西,
    线程等等。spring mvc中一个一个的用户的请求。
      SecurityManager:安全认证管理器。是shiro的核心,会在安全认证管理器中所做所有的认证操作。类似于之前
    spring mvc中的前端控制器(DispacherServlet)
      Realm: 域的意思。负责访问安全认证数据。shiro 框架并不存储安全认证数据,安全认证数据需要用户自己存
    储。shiro支持很多的Realm实现,也就 是说安全认证数据我们可以放到数据库中,也可以放到文件中等等。
    可以把realm理解为以前web项目中的dao层。
    shiro的认证 
    要做一个最简单的shiro的框架。实现的功能:用户的登录身份认证。用户如果用户名和密码都输入正确,认证成功,否则认证失败。
    第一步,新建maven项目,导入shiro的jar包 
    现在使用的maven项目还是一个简单的java项目,暂时不使用web项目。 
    <!--导入shiro依赖的commons-loggin的jar包-->
    <dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.0.4</version>
    </dependency>
    <!--导入shiro的jar包-->
    <dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.2.3</version>
    </dependency>
    第二步,创建shiro的认证文件 
    这次我们需要把用户的认证信息放到认证文件中。在resources下面建立shiro.ini: 
    #声明用户的对象
    [users]
    #=号前面是用户名 后面是密码
    zhang=123456
    li=654321
    第三步,创建测试类 
    /**
    * 测试shiro身份认证
    */
    public class Test01 {
    public static void main(String[] args) {
    //创建生成SecurityManager的工厂类对象
    Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
    //创建SecurityManager对象
    SecurityManager securityManager = factory.getInstance();
    //把SecurityManager对象设置给SecurityUtils对象
    SecurityUtils.setSecurityManager(securityManager);
    //获取验证的主题,主题是用户对象
    Subject subject = SecurityUtils.getSubject();
    //声明要比对的用户名和密码的用户对象 相当于之前前台传过来的要校验的用户登录的信息
    UsernamePasswordToken token = new UsernamePasswordToken("zhansdd","123");
    try {
    //进行用户校验
    subject.login(token);
    System.out.println("校验成功");
    }catch (UnknownAccountException e){
    System.out.println("您输入的用户名不存在");
    }catch (IncorrectCredentialsException e){
    System.out.println("您输入的密码不正确");
    }catch (AuthenticationException e){
    System.out.println("校验失败");
    }
    //退出登录
    subject.logout();
    }
    }

    realm

    realm是用来读取认证的数据,上一个例子的认证的数据是存储在配置文件中的,一般项目认证数据都不会存到配
    置文件中,一般在数据中,所以针对这种情况 我们就需要自定义realm。 
    自定义realm
    第一步,声明自定义realm
    /**
    * 自定义realm1
    */
    public class MyRealm implements Realm {
    //设置本realm的名称
    public String getName() {
    return "MyRealm1";
    }
    //设置本realm支持什么样的数据校验
    public boolean supports(AuthenticationToken authenticationToken) {
    return authenticationToken instanceof UsernamePasswordToken;
    }
    //获取认证信息
    public AuthenticationInfo getAuthenticationInfo(AuthenticationToken authenticationToken) throws
    AuthenticationException {
    //获取用户传递过来的用户名和密码
    String username = (String)authenticationToken.getPrincipal();
    String password = new String((char[])(authenticationToken.getCredentials()));
    //根据用户名和密码查询数据库,看看能不能查询到数据
    if(username.equals("zhangsan")&&password.equals("123456")){
    return new SimpleAuthenticationInfo(username,password,this.getName());
    }else{
    //校验失败 抛出校验失败异常
    throw new AuthenticationException("用户名或者密码错误");
    }
    }
    }
    第二步,在shiro的主配置文件中声明我们自定义的realm
    创建shiro的主配置文件shiro-custom.ini:
    #声明自定义的realm
    myRealm1=com.aaa.shiro.realm.MyRealm
    #设置安全管理器使用我们自定义的realm
    securityManager.realms=$myRealm1
    第三步,测试
    /**
    * 测试shiro身份认证 自定义realm
    */
    public class Test02 {
    public static void main(String[] args) {
    //创建生成SecurityManager的工厂类对象
    Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-custom.ini");
    //创建SecurityManager对象
    SecurityManager securityManager = factory.getInstance();
    //把SecurityManager对象设置给SecurityUtils对象
    SecurityUtils.setSecurityManager(securityManager);
    //获取验证的主题,主题是用户对象
    Subject subject = SecurityUtils.getSubject();
    //声明要比对的用户名和密码的用户对象 相当于之前前台传过来的要校验的用户登录的信息
    UsernamePasswordToken token = new UsernamePasswordToken("zhangsan123","123456");
    try {
    //进行用户校验
    subject.login(token);
    System.out.println("校验成功");
    }catch (UnknownAccountException e){
    System.out.println("您输入的用户名不存在");
    }catch (IncorrectCredentialsException e){
    System.out.println("您输入的密码不正确");
    }catch (AuthenticationException e){
    System.out.println("校验失败");
    }
    //退出登录
    subject.logout();
    }
    }
    JdbcRealm
    jdbcRealm的实现允许我们从一个数据源中读取认证的数据,只需要简单的配置即可。
    假如要从oracle数据库中读取认证数据
    第一步,在oracle中创建用户认证需要的表
    JdbcRealm默认会找数据库中名称为Users的表进行查询,Users必须要有username列,password列。 
    第二步,引入oracle的驱动包,数据库连接池实现的包dbcp 
    第三步,在shiro主配置文件中配置JdbcRealm
    在resources下面创建shiro-jdbcrealm.ini: 
    #声明数据源
    dataSource=org.apache.commons.dbcp.BasicDataSource
    #声明数据源的一些链接的属性
    dataSource.driverClassName=oracle.jdbc.driver.OracleDriver
    dataSource.url=jdbc:oracle:thin:@localhost:1521:orcl
    dataSource.username=scott
    dataSource.password=tiger
    #声明jdbcrealm
    jdbcrealm=org.apache.shiro.realm.jdbc.JdbcRealm
    #声明jdbcrealm需要用到的数据源属性
    jdbcrealm.dataSource=$dataSource
    ##设置安全管理器使用的jdbcrealm
    securityManager.realms=$jdbcrealm
    第四步,测试
    /**
    * 测试shiro身份认证 自定义realm
    */
    public class Test03 {
    public static void main(String[] args) {
    //创建生成SecurityManager的工厂类对象
    Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-jdbcrealm.ini");
    //创建SecurityManager对象
    SecurityManager securityManager = factory.getInstance();
    //把SecurityManager对象设置给SecurityUtils对象
    SecurityUtils.setSecurityManager(securityManager);
    //获取验证的主题,主题是用户对象
    Subject subject = SecurityUtils.getSubject();
    //声明要比对的用户名和密码的用户对象 相当于之前前台传过来的要校验的用户登录的信息
    UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","123456");
    try {
    //进行用户校验
    subject.login(token);
    System.out.println("校验成功");
    }catch (UnknownAccountException e){
    System.out.println("您输入的用户名不存在");
    }catch (IncorrectCredentialsException e){
    System.out.println("您输入的密码不正确");
    }catch (AuthenticationException e){
    e.printStackTrace();
    System.out.println("校验失败");
    }
    //退出登录
    subject.logout();
    }
    }
  • 相关阅读:
    4
    把URL传递参数转变成自定义实体方法
    【转载】C#后台声明式验证,远离if验证
    判断访问浏览器版本
    用属性动画模仿展开菜单
    N个数随机相加得出固定值的排列组合
    css3--box-shadow
    学习仅仅是靠意志力吗
    cmd 输入php出错
    切图注意事项
  • 原文地址:https://www.cnblogs.com/duguangming/p/11045644.html
Copyright © 2020-2023  润新知