apache shiro 实战

因为公司用到了shiro,所以自己抽空写了个小例子,方便下次查阅:

1.这是项目大致构架图(至于类的实际内容会在后面有贴出):

2.数据结构说明:

User:用户,包含 userName,password

Role:角色,包含roleName

Permission:权限,包含premissionName

SecurityService 是数据访问接口,实现类内容如下:

package org.pan.service.impl;

import org.pan.bean.Permission;
import org.pan.bean.Role;
import org.pan.bean.User;
import org.pan.service.SecurityService;

import java.util.HashSet;
import java.util.Set;

/**
 * Created by panmingzhi on 2014/6/25.
 */
public class SecurityServiceImpl implements SecurityService {

    @Override
    public Set<Permission> findPermissionsByRoleName(String roleName) {
        HashSet<Permission> result = new HashSet<Permission>();
        if(roleName.equals("admin")){
            result.add(new Permission("carpark:*"));
        }
        if(roleName.equals("manager")){
            result.add(new Permission("carpark:view"));
        }
        return result;
    }

    @Override
    public Set<Role> findRoleByUserName(String userName) {
        if(userName.equals("pan")){
            HashSet<Role> roles = new HashSet<Role>();
            roles.add(new Role("admin"));
            return roles;
        }

        if(userName.equals("fang")){
            HashSet<Role> roles = new HashSet<Role>();
            roles.add(new Role("manager"));
            return roles;
        }
        return new HashSet<Role>();
    }

    @Override
    public User findUserByUserName(String username) {
        if(username.equals("pan")){
            return new User("pan","1234");
        }

        if(username.equals("fang")){
            return new User("fang","1234");
        }
        return null;
    }
}

3. shiro最终权限控制实现MyRealm.class

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.pan.bean.Permission;
import org.pan.bean.Role;
import org.pan.bean.User;
import org.pan.service.SecurityService;
import org.pan.service.impl.SecurityServiceImpl;

import java.util.Iterator;
import java.util.Set;

/**
 * Created by panmingzhi on 2014/6/24.
 */
public class MyRealm extends AuthorizingRealm {

    private SecurityService securityService = new SecurityServiceImpl();

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo sai = new SimpleAuthorizationInfo();
        String userName = (String)principalCollection.fromRealm(getName()).iterator().next();
        //查找所拥有角色
        Set<Role> roleSet = securityService.findRoleByUserName(userName);
        Iterator<Role> iterator = roleSet.iterator();
        while(iterator.hasNext()){
            Role role = iterator.next();
            sai.addRole(role.getRoleName());
            //查找资源操作权限
            Set<Permission> permissionsByRoleName = securityService.findPermissionsByRoleName(role.getRoleName());
            Iterator<Permission> permissionIterator = permissionsByRoleName.iterator();
            while(permissionIterator.hasNext()){
                sai.addStringPermission(permissionIterator.next().getPremissionName());
            }
        }
        return sai;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        User user = securityService.findUserByUserName(token.getUsername());
        if (user != null) {
            return new SimpleAuthenticationInfo(user.getUserName(), user.getPassword(), getName());
        } else {
            return null;
        }
    }

}

4.功能测试ShiroTest.class

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * Created by panmingzhi on 2014/6/25.
 */
public class ShiroTest {

    @BeforeClass
    public static void before(){
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager(new MyRealm());
        SecurityUtils.setSecurityManager(defaultSecurityManager);
    }

    @Test
    public void loginTestSuccess(){
        UsernamePasswordToken upt = new UsernamePasswordToken("pan","1234");
        SecurityUtils.getSubject().login(upt);
    }

    @Test(expected = IncorrectCredentialsException.class)
    public void loginTestFaile(){
        UsernamePasswordToken upt = new UsernamePasswordToken("pan","12345");
        SecurityUtils.getSubject().login(upt);
    }

    @Test
    public void premissionTest(){
        //管理员用户登陆
        UsernamePasswordToken upt = new UsernamePasswordToken("pan","1234");
        SecurityUtils.getSubject().login(upt);

        //断断是否有管理员角色
        boolean admin = SecurityUtils.getSubject().hasRole("admin");
        Assert.assertEquals(true,admin);

        //判断是否有普通管理员角色
        boolean manager = SecurityUtils.getSubject().hasRole("manager");
        Assert.assertEquals(false,manager);

        //premission中写道:carpark.* 代表停车场中所有权限
        //判断是否有停车场修改权限
        boolean permitted = SecurityUtils.getSubject().isPermitted("carpark:edit");
        Assert.assertEquals(true,permitted);

        //判断是否有停车场查看权限
        boolean permitted2 = SecurityUtils.getSubject().isPermitted("carpark:view");
        Assert.assertEquals(true,permitted2);
    }

    @Test
    public void premissionTest2(){
        //管理员用户登陆
        UsernamePasswordToken upt = new UsernamePasswordToken("fang","1234");
        SecurityUtils.getSubject().login(upt);

        //断断是否有管理员角色
        boolean admin = SecurityUtils.getSubject().hasRole("admin");
        Assert.assertEquals(false,admin);

        //判断是否有普通管理员角色
        boolean manager = SecurityUtils.getSubject().hasRole("manager");
        Assert.assertEquals(true,manager);

        //判断是否有停车场修改权限
        boolean permitted = SecurityUtils.getSubject().isPermitted("carpark:edit");
        Assert.assertEquals(false,permitted);

        //判断是否有停车场查看权限
        boolean permitted2 = SecurityUtils.getSubject().isPermitted("carpark:view");
        Assert.assertEquals(true,permitted2);
    }
}

在实际的项目中,判断角色与权限我一般喜欢用shiro自带的注解进行完成,这样可以使权限控制与业务代码分离。
项目源码:https://github.com/panmingzhi815/shiro.git

apache shiro 实战,布布扣,bubuko.com

时间: 2024-08-24 18:25:22

apache shiro 实战的相关文章

Session(数据)共享的前后端分离Shiro实战

1,前言 本文期望描述如何使用Shiro构建基本的安全登录和权限验证.本文实战场景有如下特殊需求:1,在集群和分布式环境实现session共享:2,前端只使用HTML/CSS/JS.因此无法直接使用Shiro提供的SessionManager,以及Shiro针对web应用提供的Filter拦截方式.当然,除非是一定要通过共享缓存的方式共享session,否则还是使用Shiro默认的session管理,毕竟增加独立缓存就意味着维护成本的提高和可用性的下降. 2, Shiro架构 首先一睹官方给出的

Apache Shiro 使用手册(一)Shiro架构介绍

一.什么是Shiro Apache Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能: 认证 - 用户身份识别,常被称为用户"登录": 授权 - 访问控制: 密码加密 - 保护或隐藏数据防止被偷窥: 会话管理 - 每用户相关的时间敏感的状态. 对于任何一个应用程序,Shiro都可以提供全面的安全管理服务.并且相对于其他安全框架,Shiro要简单的多. 二.Shiro的架构介绍 首先,来了解一下Shiro的三个核心组件:Subject. Security

在 Web 项目中应用 Apache Shiro

Apache Shiro 是功能强大并且容易集成的开源权限框架,它能够完成认证.授权.加密.会话管理等功能.认证和授权为权限控制的核心,简单来说,"认证"就是证明你是谁? Web 应用程序一般做法通过表单提交用户名及密码达到认证目的."授权"即是否允许已认证用户访问受保护资源.关于 Shiro 的一系列特征及优点,很多文章已有列举,这里不再逐一赘述,本文重点介绍 Shiro 在 Web Application 中如何实现验证码认证以及如何实现单点登录. 用户权限模型

拦截404页面时tomcat抛出异常: org.apache.shiro.UnavailableSecurityManagerException

404页面中包含shiro标签,当访问404页面时,抛出异常: 原因:shiro拦截器配置缺少 标红部分,缺少红色部分导致在serverlet在拦截404页面的时候没有经过shiro  从而使shiro标签解析失败引发错误. <filter-mapping>    <filter-name>shiroFilter</filter-name>    <url-pattern>/*</url-pattern> <dispatcher>RE

Apache Shiro系列(1)

Apache Shiro是啥呢,安全框架. 360百科是这么描述的:        Apache Shiro(日语"堡垒(Castle)"的意思)是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理功能,可为任何应用提供安全保障 - 从命令行应用.移动应用到大型网络及企业应用. Shiro为解决下列问题(我喜欢称它们为应用安全的四要素)提供了保护应用的API: 认证 - 用户身份识别,常被称为用户"登录"; 授权 - 访问控制; 密码加密 - 保护或隐

Apache Shiro 使用手册(二)Shiro 认证

认证就是验证用户身份的过程.在认证过程中,用户需要提交实体信息(Principals)和凭据信息(Credentials)以检验用户是否合法.最常见的"实体/凭证"组合便是"用户名/密码"组合. 一.Shiro认证过程 1.收集实体/凭据信息 Java代码   //Example using most common scenario of username/password pair: UsernamePasswordToken token = new Userna

Apache Shiro系列四:Shiro的架构

Shiro的设计目标就是让应用程序的安全管理更简单.更直观. 软件系统一般是基于用户故事来做设计.也就是我们会基于一个客户如何与这个软件系统交互来设计用户界面和服务接口.比如,你可能会说:“如果用户登录了我们的系统,我就给他们显示一个按钮,点击之后可以查看他自己的账户信息.如果没有登录,我就给他显示一个注册按钮.” 上述应用程序在很大程度上是为了满足用户的需求而编写的,即便这个“用户”不是人,而是一个其他的软件系统.你仍然是按照谁当前正在与你的系统交互的逻辑来编写你的逻辑代码. Shiro的设计

Apache Shiro学习笔记(九)Spring集成

鲁春利的工作笔记,好记性不如烂笔头 Integrating Apache Shiro into Spring-based Applications Shiro 的组件都是JavaBean/POJO 式的组件,所以非常容易使用Spring进行组件管理,可以非常方便的从ini配置迁移到Spring进行管理,且支持JavaSE应用及Web 应用的集成. Web Applications 1.web.xml <!-- The filter-name matches name of a 'shiroFil

Caused by: java.lang.ClassNotFoundException: org.apache.shiro.spring.LifecycleBeanPostProcessor

1.错误描述 Caused by: java.lang.ClassNotFoundException: org.apache.shiro.spring.LifecycleBeanPostProcessor at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50) at org.codehaus.plexus.classworlds.realm.ClassRe