SAAS-06JWT的权限控制与Shiro入门-CSDN博客

210 阅读7分钟

第5章 权限管理与Shiro入门

1 前端权限控制

1.1 需求分析

1.1.1 需求说明

基于前后端分离的开发模式中,权限控制分为前端页面可见性权限与后端API接口可访问行权限。前端的权限控制 主要围绕在菜单是否可见,以及菜单中按钮是否可见两方面展开的。 1.1.2 实现思路 在vue工程中,菜单可以简单的理解为vue中的路由,只需要根据登录用户的权限信息动态的加载路由列表就可以 动态的构造出访问菜单。 1. 登录成功后获取用户信息,包含权限列表(菜单权限,按钮权限) 2. 根据用户菜单权限列表,动态构造路由(根据路由名称和权限标识比较) 3. 页面按钮权限通过自定义方法控制可见性

2 有状态服务和无状态服务

2.1 什么是服务中的状态

有状态和无状态服务是两种不同的服务架构,两者的不同之处在于对于服务状态的处理。服务状态是服务请求所需 的数据,它可以是一个变量或者一个数据结构。无状态服务不会记录服务状态,不同请求之间也是没有任何关系; 而有状态服务则反之。对服务器程序来说,究竟是有状态服务,还是无状态服务,其判断依据——两个来自相同发 起者的请求在服务器端是否具备上下文关系。 2.2 无状态服务 无状态请求,服务器端所能够处理的数据全部来自于请求所携带的信息,无状态服务对于客户端的单次请求的处 理,不依赖于其他请求,处理一次请求的信息都包含在该请求里。最典型的就是通过cookie保存token的方式传输 请求数据。也可以理解为Cookie是通过客户端保持状态的解决方案。

2.3 有状态服务 有状态服务则相反,服务会存储请求上下文相关的数据信息,先后的请求是可以有关联的。例如,在Web 应用 中,经常会使用Session 来维系登录用户的上下文信息。虽然http 协议是无状态的,但是借助Session,可以使 http 服务转换为有状态服务

3 基于JWT的API鉴权

3.1 基于拦截器的token与鉴权 如果我们每个方法都去写一段代码,冗余度太高,不利于维护,那如何做使我们的代码看起来更清爽呢?我们可以 将这段代码放入拦截器去实现

3.1.1 Spring中的拦截器 Spring为我们提供了org.springframework.web.servlet.handler.HandlerInterceptorAdapter这个适配器,继承此 类,可以非常方便的实现自己的拦截器。他有三个方法:分别实现预处理、后处理(调用了Service并返回 ModelAndView,但未进行页面渲染)、返回处理(已经渲染了页面) 1.在preHandle中,可以进行编码、安全控制等处理; 2.在postHandle中,有机会修改ModelAndView; 3. 在afterCompletion中,可以根据ex是否为null判断是否发生了异常,进行日志记录。 3.2 签发用户API权限

设置拦截器


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1.通过request获取请求token信息
        String authorization = request.getHeader("Authorization");
        //判断请求头信息是否为空,或者是否已Bearer开头
        if(!StringUtils.isEmpty(authorization) && authorization.startsWith("Bearer")) {
            //获取token数据
            String token = authorization.replace("Bearer ","");
            //解析token获取claims
            Claims claims = jwtUtils.parseJwt(token);
            if(claims != null) {
                //通过claims获取到当前用户的可访问API权限字符串
                String apis = (String) claims.get("apis");  //api-user-delete,api-user-update
                //通过handler
                HandlerMethod h = (HandlerMethod) handler;
                //获取接口上的reqeustmapping注解
                RequestMapping annotation = h.getMethodAnnotation(RequestMapping.class);
                //获取当前请求接口中的name属性
                String name = annotation.name();
                //判断当前用户是否具有响应的请求权限
                if(apis.contains(name)) {
                    request.setAttribute("user_claims",claims);
                    return true;
                }else {
                    throw new CommonException(ResultCode.UNAUTHORISE);
                }
            }
        }
        throw new CommonException(ResultCode.UNAUTHENTICATED);
    }

添加完拦截器

4 Shiro安全框架

4.1 什么是Shiro

4.1.1 什么是Shiro Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的 API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。 Apache Shiro 的首要目标是易于使用和理解。安全有时候是很复杂的,甚至是痛苦的,但它没有必要这样。框架 应该尽可能掩盖复杂的地方,露出一个干净而直观的 API,来简化开发人员在使他们的应用程序安全上的努力。以 下是你可以用 Apache Shiro 所做的事情: 验证用户来核实他们的身份 对用户执行访问控制,如: 判断用户是否被分配了一个确定的安全角色 判断用户是否被允许做某事 在任何环境下使用 Session API,即使没有 Web 或 EJB 容器。 在身份验证,访问控制期间或在会话的生命周期,对事件作出反应。 聚集一个或多个用户安全数据的数据源,并作为一个单一的复合用户“视图”。 启用单点登录(SSO)功能。 为没有关联到登录的用户启用"Remember Me"服务

4.1.2 与Spring Security的对比

Shiro: Shiro较之 Spring Security,Shiro在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势。

1. 易于理解的 Java Security API; 2. 简单的身份认证(登录),支持多种数据源(LDAP,JDBC,Kerberos,ActiveDirectory 等);

3. 对角色的简单的签权(访问控制),支持细粒度的签权; 4. 支持一级缓存,以提升应用程序的性能; 5. 内置的基于 POJO 企业会话管理,适用于 Web 以及非 Web 的环境; 6. 异构客户端会话访问; 7. 非常简单的加密 API; 8. 不跟任何的框架或者容器捆绑,可以独立运行 Spring Security: 除了不能脱离Spring,shiro的功能它都有。而且Spring Security对Oauth、OpenID也有支持,Shiro则需要自己手 动实现。Spring Security的权限细粒度更高。 4.1.3 Shiro的功能模块 Shiro可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在JavaEE环境。Shiro可以帮助 我们完成:认证、授权、加密、会话管理、与Web集成、缓存等。这不就是我们想要的嘛,而且Shiro的API也是非 常简单;其基本功能点如下图所示

Subject:主体,可以看到主体可以是任何可以与应用交互的“用户”; SecurityManager:相当于SpringMVC中的DispatcherServlet或者Struts2中的FilterDispatcher;是Shiro的心 脏;所有具体的交互都通过SecurityManager进行控制;它管理着所有Subject、且负责进行认证和授权、及会 话、缓存的管理。 Authenticator:认证器,负责主体认证的,这是一个扩展点,如果用户觉得Shiro默认的不好,可以自定义实 现;其需要认证策略(Authentication Strategy),即什么情况下算用户认证通过了; Authrizer:授权器,或者访问控制器,用来决定主体是否有权限进行相应的操作;即控制着用户能访问应用中的 哪些功能; Realm:可以有1个或多个Realm,可以认为是安全实体数据源,即用于获取安全实体的;可以是JDBC实现,也可 以是LDAP实现,或者内存实现等等;由用户提供;注意:Shiro不知道你的用户/权限存储在哪及以何种格式存储; 所以我们一般在应用中都需要实现自己的Realm; SessionManager:如果写过Servlet就应该知道Session的概念,Session呢需要有人去管理它的生命周期,这个 组件就是SessionManager;而Shiro并不仅仅可以用在Web环境,也可以用在如普通的JavaSE环境、EJB等环境; 所有呢,Shiro就抽象了一个自己的Session来管理主体与应用之间交互的数据; SessionDAO:DAO大家都用过,数据访问对象,用于会话的CRUD,比如我们想把Session保存到数据库,那么可 以实现自己的SessionDAO,通过如JDBC写到数据库;比如想把Session放到Memcached中,可以实现自己的 Memcached SessionDAO;另外SessionDAO中可以使用Cache进行缓存,以提高性能; CacheManager:缓存控制器,来管理如用户、角色、权限等的缓存的;因为这些数据基本上很少去改变,放到 缓存中后可以提高访问的性能 Cryptography:密码模块,Shiro提高了一些常见的加密组件用于如密码加密/解密的

Shiro认证

Shiro认证