zoukankan      html  css  js  c++  java
  • shiro权限笔记

    shiro框架运行流程

    认证:系统提供的用于识别用户身份的功能,通常就是登录功能。----让系统知道你是谁??
    授权:系统提供的为用户分配访问系统某些功能的能力。----让系统知道你能做什么??

    官网:http://shiro.apache.org/

    shiro运行流程

    Application Code:应用程序代码,由开发人员负责开发
    Subject:主体,当前用户
    SecurityManager:安全管理器,由shiro框架提供,可以管理所有的主体
    Realm:安全数据桥,类似于系统中的Dao,负责访问安全数据(权限、角色、用户)

    shiro框架核心功能

    1、认证
    2、授权
    3、会话管理
    4、加密

    shiro框架提供的权限控制方式

    1、URL拦截
    2、方法注解
    3、页面标签
    4、代码级别

    涉及的jar包

    拦截参数

    Shiro 的默认Filter 对应的类

     

    filter过滤器别名

    描述

    类路径

    anon

    匿名过滤器

    org.apache.shiro.web.filter.authc.AnonymousFilter

    authc

    认证后过滤器

    org.apache.shiro.web.filter.authc.FormAuthenticationFilter

    perms

    权限过滤器

    org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter

    port

     

    org.apache.shiro.web.filter.authz.PortFilter

    rest

     

    org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter

    noSessionCreation

     

    org.apache.shiro.web.filter.session.NoSessionCreationFilter

    authcBasic

     

    org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter

    roles

    角色过滤器

    org.apache.shiro.web.filter.authz.RolesAuthorizationFilter

    ssl

    安全协议过滤器

    org.apache.shiro.web.filter.authz.SslFilter

    user

    用户过滤器

    org.apache.shiro.web.filter.authc.UserFilter

    logout

    退出过滤器

    org.apache.shiro.web.filter.authc.LogoutFilter

    anon:    例如/admins/**=anon 没有参数,表示可以匿名使用。
    authc:   例如/admins/user/**=authc表示需要认证(登录)才能使用,没有参数
    roles:  例如/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。
    perms:例如/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
    rest:   例如/admins/user/**=rest[user],根据请求的方法,相当于
    /admins/user/**=perms[user:method] ,其中method为post,get,delete等。
    port:    例如/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?号后面的参数。
    authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证
    ssl:        例如/admins/user/**=ssl没有参数,表示安全的url请求,协议为https
    user:    例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查
    注:anon,authcBasic,auchc,user是认证过滤器,
    perms,roles,ssl,rest,port是授权过滤器

    /**代表所有子包都能匹配

    web.xml配置

    <!-- spring提供用于整合shiro的过滤器 -->
        <filter>
            <filter-name>shiroFilter</filter-name>
            <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        </filter>

    使用shiro提供的方式进行认证

    /*
     * 用户登录的方法-shiro提供的方式
     */
        public String login() {
            // 从session中获取自动生成验证码
            String key = (String) ServletActionContext.getRequest().getSession().getAttribute("key");
            // 判断输入的验证码是否为空
            if (StringUtils.isNotBlank(checkcode) && checkcode.equals(key)) {    
            //获得一个Subject对象
            Subject subject = SecurityUtils.getSubject();//用户认证状态为“未认证”
            //用户名密码令牌
            AuthenticationToken token =new UsernamePasswordToken(model.getUsername(),
                MD5Utils.md5(model.getPassword()));//密码加密,和数据库对应
                try{
                    subject.login(token);
                    //获取签名对象
                    User user = (User) subject.getPrincipal();
                    // 将对象写回浏览器的session
               ServletActionContext.getRequest().getSession().setAttribute("loginUser", user);
                    return HOME;
                }catch (UnknownAccountException e) {//shiro框架提供的异常,通过安全管理器捕获,账号不存在异常(原因是认证方法返回的是null)
                    e.printStackTrace();
                    return LOGIN;
                }catch (IncorrectCredentialsException e) {//shiro框架提供的异常,通过安全管理器捕获,密码错误异常
                    e.printStackTrace();
                    return LOGIN;
                }
            } else {
                // 验证码错误,返回登录页面
                this.addActionError(this.getText("checkcodeerror"));
                return LOGIN;
            }
        }     

    自定义realm,实现认证和授权方法

    /**
     * 自定义realm
     */
    public class BosRealm extends AuthorizingRealm {
        // 注入dao
        @Autowired
        private IUserDao userDao;
        /**
         * 认证方法
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            // 获取令牌(action传过来的token),强转成UsernamePasswordToken
            UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
            // 得到页面输入的用户名
            String username = usernamePasswordToken.getUsername();
            // 根据用户名到数据库中查询密码
            User user = userDao.findUserByUsername(username);
            if (username == null) {
                return null;
            }
            String password = user.getPassword();
            Object principal = user;// 签名对象
            Object credentials = password;// 数据库中的密码
            String realmName = this.getName();// 当前realm的名称
            AuthenticationInfo info = new SimpleAuthenticationInfo(principal, credentials, realmName);
            return info;
        }
    

    JdbcRealm加盐,MD5加密(纯数字的不安全)

    实现加密方式:MD5(用户名+密码)或者MD5(MD5(用户名+密码))
    第六步:在自定义Realm中实现授权方法

       /**
         * 授权方法
         */
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            //简单授权信息对象
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            info.addStringPermission("admin");//为当前用户授权--admin权限
            info.addRole("admin");//为当前用户授予admin角色
            User user = (User) principals.getPrimaryPrincipal();
            //TODO 后期需要连接数据库,查询当前登录人对应的实际的权限
            return info;
        }

    shiro权限控制注解方式
    在applicationContext.xml中开启shiro注解支持

    <!-- 开启shiro注解支持 -->
        <!-- 自动代理 -->
        <bean id="defaultAdvisorAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
            <!--强制使用cglib创建action的代理, 
                不配置,spring默认是使用JDK代理, 
                 默认情况下,action有接口就会使用JDK代理 -->
            <property name="proxyTargetClass" value="true"></property>
        </bean>
        <!-- 切面类 -->
        <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"></bean>     

    在Action的方法上加入shiro提供的注解

    /*
     * 批量作废功能
     */
        @RequiresPermissions(value="delete")//执行这个方法,需要有delete这个权限
        public String deleteBatch() {
           userService.delete(id);
            return LIST;
        }     

    修改BaseAction的构造方法(判断是JDK代理还是cglib代理)

    ParameterizedType genericSuperclass =null;
            Type genericSuperclass2 = this.getClass().getGenericSuperclass();
            if(genericSuperclass2 instanceof ParameterizedType){
                //this为JDK创建的代理对象
                genericSuperclass =(ParameterizedType) this.getClass().getGenericSuperclass();
            }else{
                //this为cglib创建的代理对象
                genericSuperclass =(ParameterizedType) this.getClass().getSuperclass().getGenericSuperclass();
            }     

     创建权限模块数据模型(权限表、角色表、用户表、角色权限关系表、用户角色关系表)

    用户和权限不直接建立关系,是为了方便后期授权

  • 相关阅读:
    APS.NET MVC + EF (14)---项目框架搭建
    APS.NET MVC + EF (11)---过滤器
    APS.NET MVC + EF (10)---使用AJAX
    APS.NET MVC + EF (06)---模型
    APS.NET MVC + EF (08)---数据注解和验证
    APS.NET MVC + EF (07)---表单和HTML辅助方法
    APS.NET MVC + EF (05)---控制器
    错误 1 error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
    VS2010中项目配置引入GDAL
    Win7(32/64)VS2010配置编译GDAL环境(图文教程+亲测可用!)
  • 原文地址:https://www.cnblogs.com/gaogaoyanjiu/p/7764345.html
Copyright © 2011-2022 走看看