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>
原文地址:https://www.cnblogs.com/jsbk/p/9618661.html