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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM