SpringMVC+Spring Data JPA+Shiro+EasyUI简单权限管理系统

概述

一直想做一个管理系统,希望它简洁,能做一个demo使用。以后在研究学习的时候,可以在此基础上增加代码。我觉得权限管理系统很值得做,因为涉及关系数据库模式的设计,能学到很多东西。万事开头难,先做个简单的,以后再慢慢完善的。任何事情关键是要做,不能停留在想。

前端

由于之前没有多少前端编程经验,所以做起前端比较吃力。之前前端使用Bootstrap,发现需要自己编写很多前端代码,虽然花费了很多时间,但是页面做起来还是很难看。后来前端选择了EasyUI,发现特别适合做管理页面,也容易上手。当然每个框架都有其局限性,后面使用多了就知道了,就是EasyUI不够灵活,但是现在先用着,以后再选择换其他的。EasyUI官网http://www.jeasyui.com/

MVC

使用主流的SpringMVC,不但功能强大,用起来比较简单方便。
SpringMVC推荐学习网站http://www.iteye.com/blogs/subjects/kaitao-springmvc

持久化

使用spring Data JPA。这个框架真的很赞,对于简单的业务逻辑,基本不用写SQL代码。最重要的是可以根据接口名自动生成SQL代码,极大的提高了开发效率。参考http://www.ibm.com/developerworks/cn/opensource/os-cn-spring-jpa
同时也配置了hibernate,虽然现在还没是用,但准备后期和Spring Data JPA配合是用。

权限管理

选择Shiro,简单好用,容易上手。推荐学习网站http://www.iteye.com/blogs/subjects/shiro
权限模型了解http://blog.csdn.net/painsonline/article/details/7183613/

使用预览

注册

这里写图片描述

登录

这里写图片描述

管理后台

这里写图片描述

设置角色

这里写图片描述

授权

这里写图片描述

实体层

以下只是展示了部分关键代码

用户

用户和角色是N-N的关系。

@Entity
@Table(name = "sys_user")
public class User implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id; // 编号

    // 这里不能用CascadeType.ALL
    @ManyToMany(targetEntity = Role.class, cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
    @JoinTable(name = "sys_user_role", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id") , inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id") )
    private Set<Role> roles = new HashSet<>();

    @Column(unique = true)
    private String username; // 用户名

    private String password; // 密码
    private String salt; // 加密密码的盐
    private Boolean locked = Boolean.FALSE;

    private String email;

    @Column(name = "create_date")
    @Temporal(TemporalType.TIMESTAMP)
    private Date createDate = new Date();
....

角色

@Entity
@Table(name = "sys_role")
public class Role implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id; // 编号

    @OneToMany(targetEntity = Permission.class, cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
    @JoinTable(name = "sys_role_permission", joinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id") , inverseJoinColumns = @JoinColumn(name = "permission_id", referencedColumnName = "id", unique = true) )
    private List<Permission> permissions = new ArrayList<>();

    private String name;

    @Column(unique = true)
    private String role; // 角色标识 程序中判断使用,如"admin"

    private String description; // 角色描述,UI界面显示使用  

权限

权限是资源和操作的组合。也就是说一个权限意味着对一个资源的多个操作。

@Entity
@Table(name = "sys_permission")
public class Permission implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToOne(targetEntity = Resource.class, cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
    @JoinColumn(name = "resource_id", referencedColumnName = "id")
    private Resource resource;

    @ManyToMany(targetEntity = Operation.class, cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
    @JoinTable(name = "sys_permission_operation", joinColumns = @JoinColumn(name = "permission_id", referencedColumnName = "id") , inverseJoinColumns = @JoinColumn(name = "operation_id", referencedColumnName = "id") )
    private Set<Operation> operations = new HashSet<>();

    private String name;

    private String description; 

资源

@Entity
@Table(name = "sys_resource")
public class Resource implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id; // 编号

    private String name; // 资源名称

    @Column(unique = true)
    private String identity;// 资源类型

操作

@Entity
@Table(name = "sys_operation")
public class Operation implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id; // 编号

    private String name; // 操作名称

    @Column(unique = true)
    private String operation;// 操作标识

    private String description;  

简洁易用的Spring Data JPA

Spring Data可以通过解析方法名创建查询。比如方法是findByUsername(String username),则Spring Data会自动生成SQL语句select * from 表名 where username= username.所以你对于简单的操作,你只要按照Srping Data约定写出对应的方法名,Spring Data就能自动创建SQL语句,基本不需要你写SQL语句。

一般定义DAO层时,继承一个Spring Data的基本接口,比如JpaRepository,该接口能可以帮你实现增删查改的功能外,还可以帮你做分页查询和排序。

import org.springframework.data.jpa.repository.JpaRepository;
import com.myweb.entity.User;
public interface UserDao extends JpaRepository<User, Long> {
    User findByUsername(String username);
} 

使用时,直接注入就可以了

    @Inject
    private UserDao userDao; 

Shiro认证与授权

shiro比Spring Security简单,在实现认证授权的时候,继承一个Realm类然后扩展,这里使用AuthorizingRealm。
Realm在shiro中类似数据源,认证和授权的数据就依靠它。

public class UserRealm extends AuthorizingRealm {
    @Inject
    private UserService userService;
    @Inject
    private UserDao userDao;
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 授权
        String username = (String) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(userService.getStringRoles(username));
        authorizationInfo.setStringPermissions(userService.getStringPermissions(username));
        return authorizationInfo;
    }
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
            throws AuthenticationException {
        // 认证
        String username = (String) authenticationToken.getPrincipal();
        User user = userDao.findByUsername(username);
        // 查出是否有此用户
        if (user == null) {
            throw new UnknownAccountException();// 没找到帐号
        }
        if (Boolean.TRUE.equals(user.getLocked())) {
            throw new LockedAccountException(); // 帐号锁定
        }
        // 交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,如果觉得人家的不好可以自定义实现
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(),
                user.getPassword(), ByteSource.Util.bytes(user.getCredentialsSalt()), getName());
        return authenticationInfo;
    }
} 

认证

需要SecurityUtils返回一个Subject,然后通过用户名和密码创建Token,使用这个Token登录验证。Subject 是 Shiro 的核心对象,基本所有身份验证、授权都是通过 Subject 完成。

  @RequestMapping(value = "/login", method = RequestMethod.POST)
    public ModelAndView login(User user) {
        ModelAndView mv = new ModelAndView();
        try {
            Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken authenticationToken = new UsernamePasswordToken(user.getUsername(),
                    user.getPassword());
            subject.login(authenticationToken);
        } catch (AuthenticationException e) {
            e.printStackTrace();
            mv.setViewName("redirect:/unauthorized");
            return mv;
        }
        mv.setViewName("redirect:/index");
        return mv;
    } 

授权

采用注解形式,简单方便

    @RequiresPermissions("user:create")
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @ResponseBody
    public String saveUser(@RequestParam String username, @RequestParam String password, @RequestParam String email,
            @RequestParam(value = "roles", required = false) List<Long> roleIds) {
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        user.setEmail(email);
        List<Role> roles = roleDao.findAll(roleIds);
        user.setRoles(new HashSet<>(roles));
        userService.save(user);
        return "OK";
    }
 
 
  • 1

支持注解需要配置

    <!-- Enable Shiro Annotations for Spring-configured beans. Only run after -->
    <!-- the lifecycleBeanProcessor has run: -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" />
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager" />
    </bean> 

XML配置

项目整体配置

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>myweb</display-name>
    <welcome-file-list>
        <welcome-file>/WEB-INF/jsp/login.jsp</welcome-file>
    </welcome-file-list>
    <!-- 加载所有的配置文件 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:config/spring-*.xml</param-value>
    </context-param>
    <!-- 配置Spring监听 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- 配置字符集 -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- 配置Session -->
    <filter>
        <filter-name>openSession</filter-name>
        <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
        <init-param>
            <param-name>singleSession</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>flushMode</param-name>
            <param-value>AUTO</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>openSession</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- 配置SpringMVC -->
    <servlet>
        <description>myweb</description>
        <display-name>myweb</display-name>
        <servlet-name>springMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:config/spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- 配置shiro -->
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app> 

配置SpringMVC

spring-mvc.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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/data/jpa
    http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
    <!-- 开启Spring MVC注解 -->
    <mvc:annotation-driven />
    <!-- 静态资源映射 -->
    <mvc:resources mapping="/static/**" location="/WEB-INF/static/" />
    <mvc:resources mapping="/html/**" location="/WEB-INF/html/" />
    <!-- 打开Spring的Annotation支持 -->
    <context:annotation-config />
    <!-- 注解扫描包 -->
    <context:component-scan base-package="com.myweb.controller" />
    <context:component-scan base-package="com.myweb.dao.imp" />
    <context:component-scan base-package="com.myweb.service.imp" />
    <context:component-scan base-package="com.myweb.security.util" />
    <!-- 配置SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <!-- <property name="dataSource" ref="dataSource" /> -->
        <property name="configLocation" value="classpath:config/hibernate.cfg.xml" />
        <property name="packagesToScan" value="com.myweb.entity" />
    </bean>
    <!-- 配置Dao要注入的hibernateTemplate -->
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    <!-- 配置Spring的事务处理 -->
    <!-- 创建事务管理器 -->
    <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    <!-- 配置AOP,Spring是通过AOP来进行事务管理的 -->
    <aop:config>
        <!-- 设置pointCut表示哪些方法要加入事务处理 -->
        <!-- 以下的事务是声明在DAO中,但是通常都会在Service来处理多个业务对象逻辑的关系,注入删除,更新等,此时如果在执行了一个步骤之后抛出异常 就会导致数据不完整,所以事务不应该在DAO层处理,而应该在service,这也就是Spring所提供的一个非常方便的工具,声明式事务 -->
        <aop:pointcut id="allMethods" expression="execution(* com.myweb.service.imp.*.*(..))" />
        <!-- 通过advisor来确定具体要加入事务控制的方法 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="allMethods" />
    </aop:config>
    <!-- 配置哪些方法要加入事务控制 -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <!-- 让所有的方法都加入事务管理,为了提高效率,可以把一些查询之类的方法设置为只读的事务 -->
            <tx:method name="find*" propagation="REQUIRED" read-only="true" />
            <!-- 以下方法都是可能设计修改的方法,就无法设置为只读 -->
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="del*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="save*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>
    <!-- 开启事务注解 -->
    <tx:annotation-driven />
    <!-- 默认的视图解析器ViewResolver -->
    <bean id="defaultViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
    <!-- JPA -->
    <jpa:repositories base-package="com.myweb.dao" repository-impl-postfix="Impl" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager">
    </jpa:repositories>
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="com.myweb.entity" />
        <property name="persistenceProvider">
            <bean class="org.hibernate.ejb.HibernatePersistence" />
        </property>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="generateDdl" value="false" />
                <property name="database" value="MYSQL" />
                <property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
                <property name="showSql" value="true" />
            </bean>
        </property>
        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
        </property>
        <property name="jpaPropertyMap">
            <map>
                <entry key="hibernate.query.substitutions" value="true 1, false 0" />
                <entry key="hibernate.default_batch_fetch_size" value="16" />
                <entry key="hibernate.max_fetch_depth" value="2" />
                <entry key="hibernate.generate_statistics" value="true" />
                <entry key="hibernate.bytecode.use_reflection_optimizer" value="true" />
                <entry key="hibernate.cache.use_second_level_cache" value="false" />
                <entry key="hibernate.cache.use_query_cache" value="false" />
            </map>
        </property>
    </bean>
    <!--事务管理器配置 -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>
    <bean name="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName">
            <value>com.mysql.jdbc.Driver</value>
        </property>
        <property name="url">
            <value>jdbc:mysql://localhost:3306/myweb</value>
        </property>
        <property name="username">
            <value>root</value>
        </property>
        <property name="password" value="jiangyu" />
    </bean>
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="mappingJacksonHttpMessageConverter" />
            </list>
        </property>
    </bean>

    <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>apolication/json; charset=UTF-8</value>
            </list>
        </property>
    </bean>
    <mvc:annotation-driven>
        <mvc:argument-resolvers>
            <bean class="com.myweb.controller.CurrentUserMethodArgumentResolver" />
        </mvc:argument-resolvers>
    </mvc:annotation-driven>
</beans> 

shiro在Spring配置

spring-shiro-web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
   <!-- 凭证匹配器 -->
    <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
        <property name="hashAlgorithmName" value="md5" />
        <property name="hashIterations" value="2" />
        <property name="storedCredentialsHexEncoded" value="true" />
    </bean>

    <!-- Realm实现 -->
    <bean id="userRealm" class="com.myweb.security.realm.UserRealm">
        <property name="credentialsMatcher" ref="credentialsMatcher" />
    </bean>
    <!-- 安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="userRealm" />
    </bean>
    <!-- Shiro的Web过滤器 ,id要与web.xml一致 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
        <property name="loginUrl" value="/api/user/login.page" />
        <property name="successUrl" value="/index" />
        <property name="unauthorizedUrl" value="/unauthorized" />
        <property name="filterChainDefinitions">
            <value>
                /static/** = anon
                /api/user/login = anon
                /api/user/register* = anon
                /unauthorized = anon
                /** = authc
            </value>
        </property>
    </bean>
    <!-- Shiro生命周期处理器 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
    <!-- Enable Shiro Annotations for Spring-configured beans. Only run after -->
    <!-- the lifecycleBeanProcessor has run: -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" />
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager" />
    </bean>
</beans> 

hibernate配置

hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">
            org.hibernate.dialect.MySQLDialect
        </property>
        <property name="hibernate.connection.driver_class">
            com.mysql.jdbc.Driver
        </property>
        <property name="hibernate.connection.url">
            jdbc:mysql://localhost/myweb
        </property>
        <property name="hibernate.connection.username">
            root
        </property>
        <property name="hibernate.connection.password">
            jiangyu
        </property>
        <property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>
        <!-- ddl语句自动建表 -->
        <property name="hbm2ddl.auto">update</property>
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <property name="jdbc.fetch_size">50</property>
        <property name="jdbc.batch_size">30</property>
        <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
        <property name="hibernate.c3p0.acquireRetryAttempts">30</property>
        <property name="hibernate.c3p0.acquireIncrement">2</property>
        <property name="hibernate.c3p0.checkoutTimeout">30000</property>
        <property name="hibernate.c3p0.idleConnectionTestPeriod">120</property>
        <property name="hibernate.c3p0.maxIdleTime">180</property>
        <property name="hibernate.c3p0.initialPoolSize">3</property>
        <property name="hibernate.c3p0.maxPoolSize">50</property>
        <property name="hibernate.c3p0.minPoolSize">1</property>
        <property name="hibernate.c3p0.maxStatements">0</property>
        <!-- XML配置映射关系 <mapping resource="Employee.hbm.xml" /> -->
        <!-- 注册ORM映射文件 -->
        <!-- spring不起作用 <mapping package="com.myweb.entity"/> -->
    </session-factory>
</hibernate-configuration> 

其他说明

超级管理员用户名/密码:admin/123456。
数据库导入文件:/myweb/src/main/resources/SQL/myweb.sql
源码:https://github.com/Jdoing/myweb

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
阅读目录 1.1 编写目的 1.2 是否开源 1.1 基于RBAC 1.2 数据模型 1.1 登录 1.2 资源信息维护 1.3 角色管理 1.4 组管理 1.5 系统字典维护 1.6 系统信息维护 1.7 日志管理 1.8 操作信息维护 1.9 全局参数维护 1.10 人员信息维护 第一章 引言 1.1 编写目的 使用easyui+ssh2+shiro权限管理系统,粒度可细化到按钮及菜单级别。目前是第一个稳定版本,可实现基本的权限控制功能,并且可以使用shiro的标签对细粒度的权限进行管理。 Jar包除了几个核心包之外全部使用maven管理。 回到顶部 1.2 是否开源 完全开源免费。 第一章 设计思路 回到顶部 1.1 基于RBAC RBAC认为权限授权实际上是Who、What、How的问题。在RBAC模型中,who、what、how构成了访问权限三元组,也就是“Who对What(Which)进行How的操作”。 Who:权限的拥用者或主体(如Principal、User、Group、Role、Actor等等) What:权限针对的对象或资源(Resource、Class)。 How:具体的权限(Privilege,正向授权与负向授权)。 Operator:操作。表明对What的How操作。也就是Privilege+Resource Role:角色,一定数量的权限的集合。权限分配的单位与载体,目的是隔离User与Privilege的逻辑关系. Group:用户组,权限分配的单位与载体。权限不考虑分配给特定的用户而给组。组可以包括组(以实现权限的继承),也可以包含用户,组内用户继承 组的权限。User与Group是多对多的关系。Group可以层次化,以满足不同层级权限控制的要求。 RBAC的关注点在于Role和User, Permission的关系。称为User assignment(UA)和Permission assignment(PA).关系的左右两边都是Many-to-Many关系。就是user可以有多个role,role可以包括多个user。 回到顶部 1.2 数据模型 第一章 系统操作 回到顶部 1.1 登录 部署完成后需要输入: http://localhost:8080/sshpermission 进入登录界面 输入管理员 用户名:admin 密码:admin 进入系统 回到顶部 1.2 资源信息维护 维护系统的资源信息,资源指的是系统中所有的除按钮外的相关信息,比如菜单,首页显示列表等。 回到顶部 1.3 角色管理 维护系统角色信息,可对系统进行分配资源授权和操作授权。 角色维护 资源分配 操作分配 回到顶部 1.4 组管理 维护一组用户的信息,可以跟角色和用户进行组合。可以向组内添加用户,可以给组添加角色。 向组内添加用户 给组授权角色 回到顶部 1.5 系统字典维护 维护系统内的字典数据。 回到顶部 1.6 系统信息维护 维护系统信息,可以设置多个系统,进行多个系统的维护与授权。 回到顶部 1.7 日志管理 维护系统日志,使用AOP进行记录,可对需要维护的部分进行配置。 回到顶部 1.8 操作信息维护 维护操作信息 回到顶部 1.9 全局参数维护 维护全局参数。 回到顶部 1.10 人员信息维护 维护用户的基本信息

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值