java权限管理知识总结

最近花了三天时间跟着燕青老师学习了基于shiro框架的权限管理的设计与实现,现在总结,写一篇博客供大家共同学习和交流,联系穆荣斌。

权限管理的基本知识;

    概念:只要用户参与的系统一般都有权限管理模块,权限管理主要实现对用户访问系统的控制,并且控制用户访问的资源和菜单'
    分类:认证和授权
        ***认证:验证用户是否合法,常用:用户名密码,指纹机,基于某种证书验证
        主体在进行身份认证时需要提供身份信息和凭证信息。

        ***授权:验证用户是否具有访问系统某些资源的权限,注意:这是基于认证通过的用户主体
        授权可以理解为:who对what/which进行how的操作

这里注意:what资源包括:资源类型和资源实例
资源类型指某些模块菜单,用户删除增加等;
资源实例指针对id为1的用户的增删查看,针对陕西省管理人员只能查看陕西省的资源而不能查看其它省的资源

权限管理的解决方案

谈到解决方案涉及到权限管理中的粗粒度权限和细粒度权限:
粗粒度权限:例如资源类型的控制,例如某个模块菜单和button按钮
解决方案:将比较容易的权限管理代码抽取出来使用struts或者springmvc拦截器来判断验证
细粒度权限:例如资源类型的实例,就是对数据级别的权限管理例如id为1的产品信息增删差等
解决方案:针对细粒度资源实例,因为业务数据的不确定性,在业务开发时就要在service层业务代码中进行判断和拦截。
*例如:部门经理只能查询本部门的员工信息,可以在controller层调用service等方法时传一个部门id给servcie层的方法,然后在servcie层进行按本部门id查询员工的信息。

权限管理的模型图

根据实际分析可以将权限模型概括如下:
主体:账号和密码
资源:资源名称和访问地址
权限:权限名称和资源id
角色:角色名称和id
权限与角色:权限id和角色id
用户与角色:用户账号和角色id
一般过程中:将资源和权限合并为:权限:权限id、资源名称和资源url
这里写图片描述
基本会建立以上五张表,角色是其中的润滑剂和过度器

基于url地址的权限管理方案

思路如下:
所有的资源和全下url都要配置在数据库中或者配置文件中
流程如下:
主体登录,先认证
拦截器拦截判断是否有session,如果有登录,没有进行认证验证用户名密码是否正确,提示错误信息
授权:使用授权拦截器实现
这里写图片描述

实现思路如下:将用户对应角色的权限菜单和权限url查询出来放在session中,然后在拦截器进行拦截时获取并判断被拦截的url是否为session存在,如果存在即放行,不存在拦截提示无权限访问。

//在执行handler之前来执行的
    //用于用户认证校验、用户权限校验
    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {

        //得到请求的url
        String url = request.getRequestURI();

        //判断是否是公开 地址
        //实际开发中需要公开 地址配置在配置文件中
        //从配置中取逆名访问url

        List<String> open_urls = ResourcesUtil.gekeyList("anonymousURL");
        //遍历公开 地址,如果是公开 地址则放行
        for(String open_url:open_urls){
            if(url.indexOf(open_url)>=0){
                //如果是公开 地址则放行
                return true;
            }
        }

        //从配置文件中获取公共访问地址
        List<String> common_urls = ResourcesUtil.gekeyList("commonURL");
        //遍历公用 地址,如果是公用 地址则放行
        for(String common_url:common_urls){
            if(url.indexOf(common_url)>=0){
                //如果是公开 地址则放行
                return true;
            }
        }

        //获取session
        HttpSession session = request.getSession();
        ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
        //从session中取权限范围的url
        List<SysPermission> permissions = activeUser.getPermissions();
        for(SysPermission sysPermission:permissions){
            //权限的url
            String permission_url = sysPermission.getUrl();
            if(url.indexOf(permission_url)>=0){
                //如果是权限的url 地址则放行
                return true;
            }
        }

        //执行到这里拦截,跳转到无权访问的提示页面
        request.getRequestDispatcher("/WEB-INF/jsp/refuse.jsp").forward(request, response);

        //如果返回false表示拦截不继续执行handler,如果返回true表示放行
        return false;
    }

基于shiro框架的权限管理方案

目前市面上流行Apache的shiro框架和spring的security,由于后者对spring依赖过于强烈,所以多用于shiro

  1. shiro架构
    这里写图片描述
    其中不管是认证器还是授权器都是要操作realm来判断实现的

  2. shiro实现流程
    这里写图片描述
    认证流程如下:
    用户或者某个程序登录,在spring中配置或者搭建SecurityManager环境,然后用户登录,然后SecurityManager通过调用Authenticator来执行shiro框架默认的Realm或者自定义realm来根据身份信息验证用户是否正确来进行登录认证,
    同理授权也一样,所有的判断都会通过SecurityManager安全管理器来调用Authorizor来执行realm判断该主体用户是否拥有被拦截地址的权限来进行权限判断

  3. 自定义realm

public class CustomRealm extends AuthorizingRealm {

@Autowired
private SystemService systemService;

//设置realm名字
@Override
public void setName(String name) {
    super.setName("customRealm");
}

//认证
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
    //第一步:从token中获取用户凭证信息******类似基于url权限管理中心的activtyuser记录用户信息
    String userCode = (String) authenticationToken.getPrincipal();
    //第二步:拿着用户名从数据库中查密码,如果查不到返回null
    SysUser sysUser = null;
    try {
        sysUser = systemService.findSysUser(userCode);
    } catch (Exception e) {
        e.printStackTrace();
    }
    if (sysUser == null) {
        return null;
    }
    //如果查询到密码
    String password = sysUser.getPassword();
    //查询盐,用于验证密码是否正确
    String salt = sysUser.getSalt();
    //查询用户菜单和url
    List<SysPermission> menus = systemService.findPermissionMenue(userCode);
    List<SysPermission> urls = systemService.findPermissionUrl(userCode);
    ActiveUser activeUser = new ActiveUser();
    activeUser.setUserid(userCode);
    activeUser.setUsercode(userCode);
    activeUser.setUsername(activeUser.getUsername());
    activeUser.setMenues(menus);
    activeUser.setPermissionUrls(urls);
    //然后获得认证信息并返回
    SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(activeUser, password, ByteSource.Util.bytes(salt), this.getName());
    return simpleAuthenticationInfo;    
}

//授权
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

    //第一步:从principalCollection中获取用户信息,这是已经封装成一个对象中
    ActiveUser activeUser = (ActiveUser) principalCollection.getPrimaryPrincipal();
    //第二步:拿着用户名从数据库查询正确权限信息
       List<SysPermission> permissions=systemService.findPermissionUrl(activeUser.getUsercode());
    List<SysPermission> permissionMenu= systemService.findPermissionMenue(activeUser.getUsercode());
    List<String> permissionList=new ArrayList<String>();
    if (permissions!=null){
        for (int i=0;i<permissions.size();i++){
            permissionList.add(permissions.get(i).getPercode());
        }
    }
    if (permissionMenu!=null){
        for (int i=0;i<permissionMenu.size();i++){
            permissionList.add(permissionMenu.get(i).getPercode());
        }
    }
    //获取权限信息并返回
    SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
    //将权限信息设置到simpleAuthorizationInfo
    simpleAuthorizationInfo.addStringPermissions(permissionList);
    return simpleAuthorizationInfo;
}
//清除缓存,在修改权限时sevice层修改
public void clearCached() {
    PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
    super.clearCache(principals);
}

}
spring整合shiro配置文件

<beans xmlns="http://www.springframework.org/schema/beans"
    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-3.2.xsd">
    <!--开启shiro注解-->
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>
    <!-- Shiro 的Web过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
        <!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
        <property name="loginUrl" value="/login.action" />
        <property name="successUrl" value="/first.action"/>
        <!--无权限跳转页面-->
        <property name="unauthorizedUrl" value="/refuse.jsp" />
        <!--注入自定认证过滤器-->
        <property name="filters">
            <map>
                <entry key="authc" value-ref="customFormAuthenticationFilter"/>
            </map>
        </property>
        <!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 左边是url,右边是shiro拦截器简称-->
        <property name="filterChainDefinitions">
            <value>
                <!-- 退出拦截,请求logout.action执行退出操作,shiro会自动清除session -->
                /logout.action = logout
                <!-- 无权访问页面 -->
                /refuse.jsp = anon
                <!-- roles[XX]表示有XX角色才可访问-->
                <!--/item/list.action = roles[item],authc-->
            <!--    /items/queryItems.action=perms[user:query]-->
                /js/** anon
                /images/** anon
                /styles/** anon
                /validatecode.jsp anon
                <!--配置记住我或者认证成功后拦截-->
                /index.jsp=user
                /first.action= user
                /welcome.jsp=user
                <!--/item/* authc-->
                <!-- user表示身份认证通过或通过记住我认证通过的可以访问 -->
                /** = authc

            </value>
        </property>
    </bean>

    <!-- 安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="customRealm" />
        <!--配置session管理器-->
        <property name="sessionManager" ref="sessionManager"/>
        <!--注入缓存bean-->
        <property name="cacheManager" ref="cacheManager"/>
        <!--记住我-->
        <property name="rememberMeManager" ref="rememberMeManage"/>
    </bean>

    <!--配置自定义认证过滤器,用于验证码判断-->
    <bean id="customFormAuthenticationFilter" class="com.cad.ssm_web.util.filter.CustomFormAuthenticationFilter">
        <property name="usernameParam" value="username"/>
        <property name="passwordParam" value="password"/>
    </bean>

    <!-- 自定义 realm -->
    <bean id="customRealm" class="com.cad.ssm_web.util.CustomRealm">
        <property name="credentialsMatcher" ref="credentialsMatcher"/>
    </bean>

    <!--凭证匹配器-->
    <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
        <!--散列算法名称-->
        <property name="hashAlgorithmName" value="md5"/>
        <!--散列算法散列次数-->
        <property name="hashIterations" value="1"/>
    </bean>

    <!--配置ehcahe缓存-->
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
    </bean>

    <!--配置session管理器-->
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <property name="globalSessionTimeout" value="60000"/>
        <!--是否删除失效的session-->
        <property name="deleteInvalidSessions" value="true"/>
        <property name="sessionIdCookie">
            <bean class="org.apache.shiro.web.servlet.SimpleCookie">
                <property name="name" value="JSESSID" />
            </bean>
        </property>
    </bean>

    <!--配置rememberMe管理器-->
    <bean id="rememberMeManage" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
        <property name="cookie" ref="rememberMeCookie"/>
    </bean>
    <!--记住我cookie-->
    <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <constructor-arg value="rememberMe"/>
        <property name="maxAge" value="2592000"/>
    </bean>
</beans>

登录controller

@RequestMapping("login")
    public String login(HttpServletRequest request) throws Exception {

        //登录失败shiro会返回一个认证异常信息,注意这是shiro设置到request域中的属性
        String exception= (String) request.getAttribute("shiroLoginFailure");
        if (exception !=null) {
            if (UnknownAccountException.class.getName().equals(exception)) {
                throw new CustomException("用户名不存在!");
            } else if (IncorrectCredentialsException.class.getName().equals(exception)) {
                throw new CustomException("用户名或密码不正确!");
            } else if ("validateCodeFaile".equals(exception)){
                throw new CustomException("验证码错误!");
            }else {
                throw new Exception();
            }
        }
        //TODO 登录失败跳转login.jsp,认证成功跳转到上一个请求
        return "login";
    }

3.使用协议
第一openid协议,解决用户的认证,比如所有互联网登陆公司遵守该协议,统一有辨识该用户的唯一标识openid,用户登录其他系统只需要验证openid即可,但是由于各个互联网公司的数据不共享,导致该协议没有遵守下去;
第二:OAuth2.0协议,解决用户授权问题,例如微信小程序获取用户信息,需要有微信服务第三方来接入,基本流程如下:小程序征求用户同意获取授权信息,授权后,小程序再去微信服务器通过token验证是否正确,然后微信服务器再将用户的授权信息发送给小程序;
第三:OIDC1.0协议,该协议完全解决了用户认证与授权的两个过程,详情见https://www.oschina.net/news/73532/oidc-oauth-2

学习博客:
http://www.sojson.com/shiro#so231722903
https://www.cnblogs.com/1315925303zxz/p/6874219.html
拦截器:http://jinnianshilongnian.iteye.com/blog/2025656

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java是一种广泛应用于开发各种类型应用程序的编程语言,而web库存管理系统是一种用于管理和跟踪库存信息的系统。下面是一个简单的Java加web库存管理系统的源码示例。 在这个示例中,我们使用Java的Spring框架来构建web应用程序,并使用MySQL数据库来存储库存信息。 首先,我们需要创建一个实体类来表示库存物品。这个类中包含物品的名称、数量和价格等属性。然后,我们使用Hibernate注解来映射这个实体类到数据库中的一张表。 接下来,我们创建一个控制器类来处理web请求。这个类包含了处理GET和POST请求的方法。当用户访问系统的主页时,控制器将查询数据库并返回所有库存物品的列表。当用户提交新的库存物品时,控制器将验证输入数据,并将其保存到数据库中。 在前端页面中,我们使用HTML和CSS来构建用户界面。使用Thymeleaf模板引擎来动态生成页面内容。在主页上,我们显示所有的库存物品,并提供一个表单来添加新的物品。 此外,我们还可以实现一些其他功能,例如更新库存物品的数量、删除物品和搜索功能等。这些功能可以在控制器类中添加相应的方法来处理用户的请求。 通过以上简单示例,我们可以看到Java加web库存管理系统的源码主要包括实体类、数据库操作、控制器类和前端页面等。通过使用Java的Spring框架和相关库,我们可以轻松构建一个功能完善的库存管理系统。 ### 回答2: Java加web库存管理源码是一个用Java语言编写的库存管理系统的源代码,它结合了Web技术的优势,可以通过网页界面实现对库存管理的各种操作。 该源码的功能包括库存商品的添加、修改、删除,商品信息的查询和展示,以及入库和出库操作等。通过网页界面,用户可以方便地进行库存管理,实时监控和掌握库存情况。 源码中使用了Java的基础知识和面向对象编程的思想,通过MVC模式进行项目的分层开发,使代码结构清晰,易于扩展和维护。同时,还使用了一些常用的框架和技术,如Spring、Spring MVC和MyBatis等,以提高开发效率和项目的稳定性。 在源码中,商品信息通过数据库进行存储,通过MySQL或其他关系型数据库进行操作。在网页界面上,用户可以通过简单的表单填写商品的各种属性,并通过点击按钮进行对应的操作。同时,界面也提供了查询功能,用户可以根据不同的条件进行商品信息的查询和展示。 通过该源码,用户可以轻松实现对库存的管理,提高库存管理的效率和准确性。可以根据需要对源码进行个性化修改,以满足不同场景下的需求。 总结起来,Java加web库存管理源码是一个功能全面、易于使用的库存管理系统的源代码。它利用了Java语言和Web技术的优势,提供了方便的网页界面和强大的功能,可以帮助用户实现高效、准确的库存管理。 ### 回答3: Java加Web库存管理源码是一个用Java语言编写的库存管理系统的源码,具有Web界面。该系统旨在帮助企业高效地管理库存,实现库存的准确监控和管理。 源码的主要功能包括: 1. 用户管理:系统提供了用户管理功能,可以添加、删除、编辑用户信息,并设置用户权限。 2. 商品管理:可以对商品进行添加、删除、编辑、查询等操作,包括商品的基本信息、分类、价格等。 3. 入库管理:实现对商品的入库操作,记录商品的进货数量和进货价格等相关信息。 4. 出库管理:实现对商品的出库操作,记录商品的销售数量和销售价格等相关信息。 5. 库存管理:实时查询库存情况,包括当前库存数量、商品分类、进货价格、销售价格等。 6. 报表统计:生成各类报表,如销售报表、进货报表等,方便查看企业的库存状况和经营情况。 7. 用户权限控制:根据用户权限设置,实现不同用户对系统功能的访问控制。 该源码采用了Java Web开发框架,如Spring MVC框架、MyBatis框架等,以实现系统的功能和交互效果。同时,还使用了HTML、CSS、JavaScript等前端技术,使系统界面友好、美观。 通过该系统,企业可以方便地管理库存,并实时掌握库存情况,提高企业的运营效率和管理水平。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值