1. 程式人生 > >Apache Shiro

Apache Shiro

權限 ebe cycle extend odi ash 路徑 pro ans

4個POJO

/**
 * @description:菜單
 */
@Entity
@Table(name = "T_MENU")
public class Menu {
    @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;
/**
 * @description:權限名稱
 */
@Entity
@Table(name = "T_PERMISSION")
public class Permission {

    @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 {
    @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 {

    @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);

在web.xml中配置filter

<!-- 配置 shiro的filter-->
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

配置applicationContext-shiro.xml文件

<?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 
                /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" />
    </bean>
    <bean id="lifecycleBeanPostProcessor"
        class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
</beans>

基於shiro登錄的部分核心代碼

        // 基於shiro實現登錄
        Subject subject = SecurityUtils.getSubject();
        AuthenticationToken authenticationToken = new UsernamePasswordToken(model.getUsername(), model.getPassword());
        
        try {
            subject.login(authenticationToken);
            return SUCCESS;
        } catch (AuthenticationException e) {
            //登錄失敗
            e.printStackTrace();
            return "login";
        }

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) {
        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 {
        //轉換taken
        UsernamePasswordToken passwordToken = (UsernamePasswordToken) token;
        //根據用戶名查詢用戶信息
        User user = userService.findByUsername(passwordToken.getUsername());
        if(user == null) {
            //用戶名不存在,
            return null;
        }else {
            //用戶名存在
            //當用戶返回密碼時,securityManager安全管理器,自動比較返回密碼和用戶輸入密碼是否一致,
            //密碼一致.登錄成功,密碼不一致,報出異常
            return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
        }
    }

}

Apache Shiro