A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 大蓝鲸Java 于 2017-12-27 16:39 编辑

一、Shiro介绍
1、Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。
2、使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
二、Shiro体系结构
1、 Authentication 认证 ---- 用户登录,身份识别
2、 Authorization 授权 --- 用户具有哪些权限、角色
3、 Cryptography 安全数据加密
4、 Session Management 会话管理
5、 Web Integration web 系统集成
6、 Integrations 集成其它应用, spring、缓存框架
三、Shiro主要运行流程
应用程序 --- Subject --- SecurityManager --- Realm --- 安全数据(数据库)
Subject介绍:
1、Subject 是与程序进行交互的对象,可以是人也可以是服务或者其他,通常就理解为用户。
2、所有 Subject 实例都被绑定到(且这是必须的)一个 SecurityManager 上。当你与一个Subject 交互时,那些交互作用转化为与 SecurityManager 交互的特定 subject 的交互作用。
SecurityManager介绍:
1、SecurityManager 是 Shiro的核心,初始化时协调各个模块运行。然而,一旦 SecurityManager协调完毕,SecurityManager 会被单独留下,且我们只需要去操作Subject即可,无需操作SecurityManager 。
2、当我们正与一个 Subject 进行交互时,实质上是 SecurityManager在处理 Subject 安全操作。
Realm介绍:
1、Realms 担当 Shiro 和你的应用程序的安全数据之间的“桥梁”或“连接器”。当它实际上与安全相
关的数据如用来执行身份验证(登录)及授权(访问控制)的用户帐户交互时, Shiro 从一个或多个为应用程序配置的 Realm 中寻找许多这样的东西。
2、在这个意义上说, Realm 本质上是一个特定安全的 DAO:它封装了数据源的连接详细信息,使 Shiro 所需的相关的数据可用。当配置 Shiro 时,你必须指定至少一个 Realm 用来进行身份验证和/或授权。 SecurityManager可能配置多个 Realms,但至少有一个是必须的。
四、Shiro的使用
1、 配置 web.xml,增加shiro的Filter
[Java] 纯文本查看 复制代码
<!-- shiro的Filter  -->
        <filter> 
                <!-- 去spring配置文件中寻找同名bean  -->
                <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>

2、在spring配置文件中,增加shiro的相关配置
[Java] 纯文本查看 复制代码
<!-- 配置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 
                         <!-- 访问courier.html页面需要有courier:list-->
                                /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" /><!-- 安全管理器调用realm-->
        </bean>

3、编写realm
[Java] 纯文本查看 复制代码
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());
                }

        }

}


五、权限控制表结构






1.png (88.03 KB, 下载次数: 18)

1.png

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马