zoukankan      html  css  js  c++  java
  • shiro权限控制用户登录的用法介绍

    在互联网用户登录的时候,我们大部分的时候要对登录的用户进行权限控制

    技术:shiro--- ssh 整合的代码

    1 shiro 包的引入

           <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.2.2</version>
    </dependency>

    2 权限表的设计思路

    一般设计四个表

    菜单表:Menu  

    权限表:Permission

    角色表:Role

    用户表:User

    /**
     * @description:菜单
     */
    @Entity
    @Table(name = "T_MENU")
    public class Menu implements Serializable {
        @Id
        @GeneratedValue
        @Column(name = "C_ID")
        private int id;
        @Column(name = "C_NAME")
        private String name; // 菜单名称
        @Column(name = "C_PAGE")
        private String page; // 访问路径
        @Column(name = "C_PRIORITY")
        private Integer priority; // 优先级
        @Column(name = "C_DESCRIPTION")
        private String description; // 描述
    
        @ManyToMany(mappedBy = "menus")
        private Set<Role> roles = new HashSet<Role>(0);
    
        @OneToMany(mappedBy = "parentMenu")
        private Set<Menu> childrenMenus = new HashSet<Menu>();
    
        @ManyToOne
        @JoinColumn(name = "C_PID")
        private Menu parentMenu;
    
        @Transient
        // 在数据表不去生成数据列
        public Integer getpId() {
            if (parentMenu == null) {
                return 0;
            } else {
                return parentMenu.getId();
            }
        }
    }
    /**
     * @description:权限名称
     */
    @Entity
    @Table(name = "T_PERMISSION")
    public class Permission implements Serializable {
    
        @Id
        @GeneratedValue
        @Column(name = "C_ID")
        private int id;
        @Column(name = "C_NAME")
        private String name; // 权限名称
        @Column(name = "C_KEYWORD")
        private String keyword; // 权限关键字,用于权限控制
        @Column(name = "C_DESCRIPTION")
        private String description; // 描述
    
        @ManyToMany(mappedBy = "permissions")
        private Set<Role> roles = new HashSet<Role>(0);
    
    }
    /**
     * @description:角色
     */
    @Entity
    @Table(name = "T_ROLE")
    public class Role implements Serializable {
        @Id
        @GeneratedValue
        @Column(name = "C_ID")
        private int id;
        @Column(name = "C_NAME")
        private String name; // 角色名称
        @Column(name = "C_KEYWORD")
        private String keyword; // 角色关键字,用于权限控制
        @Column(name = "C_DESCRIPTION")
        private String description; // 描述
    
        @ManyToMany(mappedBy = "roles")
        private Set<User> users = new HashSet<User>(0);
    
        @ManyToMany
        @JoinTable(name = "T_ROLE_PERMISSION", joinColumns = { @JoinColumn(name = "C_ROLE_ID",
    referencedColumnName = "C_ID") }, inverseJoinColumns = { @JoinColumn(name = "C_PERMISSION_ID", referencedColumnName = "C_ID") }) private Set<Permission> permissions = new HashSet<Permission>(0); @ManyToMany @JoinTable(name = "T_ROLE_MENU", joinColumns = { @JoinColumn(name = "C_ROLE_ID",
    referencedColumnName = "C_ID") }, inverseJoinColumns = { @JoinColumn(name = "C_MENU_ID", referencedColumnName = "C_ID") }) private Set<Menu> menus = new HashSet<Menu>(0); }
    /**
     * @description:后台用户
     */
    @Entity
    @Table(name = "T_USER")
    public class User implements Serializable {
    
        @Id
        @GeneratedValue
        @Column(name = "C_ID")
        private int id; // 主键
        @Column(name = "C_BIRTHDAY")
        private Date birthday; // 生日
        @Column(name = "C_GENDER")
        private String gender; // 性别
        @Column(name = "C_PASSWORD")
        private String password; // 密码
        @Column(name = "C_REMARK")
        private String remark; // 备注
        @Column(name = "C_STATION")
        private String station; // 状态
        @Column(name = "C_TELEPHONE")
        private String telephone; // 联系电话
        @Column(name = "C_USERNAME", unique = true)
        private String username; // 登陆用户名
        @Column(name = "C_NICKNAME")
        private String nickname; // 真实姓名
    
        @ManyToMany
        @JoinTable(name = "T_USER_ROLE", joinColumns = { @JoinColumn(name = "C_USER_ID", referencedColumnName = "C_ID") }, 
        inverseJoinColumns = { @JoinColumn(name = "C_ROLE_ID", referencedColumnName = "C_ID") }) private Set<Role> roles = new HashSet<Role>(0); }

     3  后台代码编写

    --1  后台访问login  

    @Action(value = "user_login", results = {
                @Result(name = "login", type = "redirect", location = "login.html"),
                @Result(name = "success", type = "redirect", location = "index.html") })
        public String login() {
            // 用户名和密码 都保存在model中
            // 基于shiro实现登录
            Subject subject = SecurityUtils.getSubject();
    
            // 用户名和密码信息
            AuthenticationToken token = new UsernamePasswordToken(
                    model.getUsername(), model.getPassword());
            try {
                subject.login(token);
                // 登录成功
                // 将用户信息 保存到 Session
                return SUCCESS;
            } catch (AuthenticationException e) {
                // 登录失败
                e.printStackTrace();
                return LOGIN;
            }
        }
    
        @Action(value = "user_logout", results = { @Result(name = "success", type = "redirect", location = "login.html") })
        public String logout() {
            // 基于shiro完成退出
            Subject subject = SecurityUtils.getSubject();
            subject.logout();
    
            return SUCCESS;
        }
    
       

    ----subject.login(token);会调用自定义Realm(配置文件配置)

    Realm 类

    // 自定义Realm ,实现安全数据 连接
    // @Service("bosRealm")
    public class BosRealm extends AuthorizingRealm {
    
        @Autowired
        private UserService userService;
    
        @Autowired
        private RoleService roleService;
    
        @Autowired
        private PermissionService permissionService;
    
        @Override
        // 授权...
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
            System.out.println("shiro 授权管理...");
            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
            // 根据当前登录用户 查询对应角色和权限
            Subject subject = SecurityUtils.getSubject();
            User user = (User) subject.getPrincipal();
            // 调用业务层,查询角色
            List<Role> roles = roleService.findByUser(user);
            for (Role role : roles) {
                authorizationInfo.addRole(role.getKeyword());
            }
            // 调用业务层,查询权限
            List<Permission> permissions = permissionService.findByUser(user);
            for (Permission permission : permissions) {
                authorizationInfo.addStringPermission(permission.getKeyword());
            }
    
            return authorizationInfo;
        }
    
        @Override
        // 认证...
        protected AuthenticationInfo doGetAuthenticationInfo(
                AuthenticationToken token) throws AuthenticationException {
            System.out.println("shiro 认证管理... ");
    
            // 转换token
            UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
    
            // 根据用户名 查询 用户信息
            User user = userService.findByUsername(usernamePasswordToken
                    .getUsername());
            if (user == null) {
                // 用户名不存在
                // 参数一: 期望登录后,保存在Subject中信息
                // 参数二: 如果返回为null 说明用户不存在,报用户名
                // 参数三 :realm名称
                return null;
            } else {
                // 用户名存在
                // 当返回用户密码时,securityManager安全管理器,自动比较返回密码和用户输入密码是否一致
                // 如果密码一致 登录成功, 如果密码不一致 报密码错误异常
                return new SimpleAuthenticationInfo(user, user.getPassword(),
                        getName());
            }
    
        }
    
    }

    4 resources  下的配置文件配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
            http://www.springframework.org/schema/data/jpa 
            http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
        
        <!-- 配置Shiro核心Filter  --> 
        <bean id="shiroFilter" 
            class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <!-- 安全管理器 -->
            <property name="securityManager" ref="securityManager" />
            <!-- 未认证,跳转到哪个页面  -->
            <property name="loginUrl" value="/login.html" />
            <!-- 登录页面页面 -->
            <property name="successUrl" value="/index.html" />
            <!-- 认证后,没有权限跳转页面 -->
            <property name="unauthorizedUrl" value="/unauthorized.html" />
            <!-- shiro URL控制过滤器规则  -->
            <property name="filterChainDefinitions">
                <value>
                    /login.html* = anon
                    /user_login.action* = anon 
                    /validatecode.jsp* = anon
                    /css/** = anon
                    /js/** = anon
                    /images/** = anon
                    /services/** = anon 
                    /pages/base/courier.html* = perms[courier:list]
                    /pages/base/area.html* = roles[base]
                    /** = authc
                </value>
            </property>
        </bean>
        
        <!-- 安全管理器  -->
        <bean id="securityManager" 
            class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="realm" ref="bosRealm" />
            <property name="cacheManager" ref="shiroCacheManager" />
        </bean>
        
        <!-- 配置Realm -->
        <bean id="bosRealm" class="cn.itcast.bos.realm.BosRealm">
            <!-- 缓存区的名字 就是 ehcache.xml 自定义 cache的name -->
            <property name="authorizationCacheName" value="bos" />
        </bean>
        
        <bean id="lifecycleBeanPostProcessor"
            class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
            
        <!-- 开启shiro注解模式  -->
        <bean
            class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
            depends-on="lifecycleBeanPostProcessor" >
            <property name="proxyTargetClass" value="true" />
        </bean>
            
        <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
             <property name="securityManager" ref="securityManager"/>
        </bean>
        
    </beans>
  • 相关阅读:
    建造者(Builder)模式
    模板方法模式(Tempalte Method Pattern)
    NIO Socket编程实例
    Java NIO概述
    转:Java中的Clone()方法详解
    调停者(Mediator)模式
    门面(Facade)模式
    struts2中方法拦截器(Interceptor)的中的excludeMethods与includeMethods的理解
    Struts2默认拦截器配置
    struts2的json-default和struts-default的区别
  • 原文地址:https://www.cnblogs.com/jsbk/p/9618661.html
Copyright © 2011-2022 走看看