公司动态
认证授权【基础概念篇】
什么是认证认证: 用户认证就是判断一个用户的身份是否合法的过程用户去访问系统资源时系统要求验证用户的身份信息身份合法方可继续访问不合法则拒绝访问。常见的用户身份认证方式有:用户名密码登录二维码登录手机短信登录指纹认证等方式。什么是会话会话就是系统为了保持当前用户的登录状态所提供的机制。简单来说就是保持登录状态直到系统退出。常见的有基于session方式、基于token方式等。基于session的认证方式它的交互流程是用户认证成功后在服务端生成用户相关的数据保存在session(当前会话)中发给客户端的 sesssion_id 存放到 cookie 中这样用户客户端请求时带上 session_id 就可以验证服务器端是否存在 session数据以此完成用户的合法校验当用户退出系统或session过期销毁时,客户端的session id也就无效了。代码实现1. 首先需要定义一个唯一的key标识当前用户public static final String SESSION USER KEY user;2. 服务端认证信息成功后通过HttpSession的setAttribute将用户信息存入到session中。3.服务端获取session信息。通过session的getAttribute方法获取存入session的用户信息。基于token的认证方式它的交互流程是用户认证成功后服务端生成一个token发给客户端,客户端可以放到 cookie 或localStorage 中存储,每次请求时带上 token,服务端收到token通过验证后即可确认用户身份。session认证和token认证的区别对服务端而言session需要将认证信息存储在服务端存在内存中session中数据中都行。token不需要存储认证信息在服务端。对客户端而言session需要将认证信息存储在cookie中每次携带认证信息到服务端校验。token可以将认证信息存储在localStoge或cookie中。什么是授权授权: 授权是用户认证通过根据用户的权限来控制用户访问资源的过程拥有资源的访问权限则正常访问没有权限则拒绝访问。如普通用户无法访问系统后台。在QQ中 没有绑定银行卡的用户无法收发红包。可以理解为没有授权就做不了权限以外的操作。RBAC基于角色的访问控制RBAC基于角色的访问控制(Role-Based Access Control)是按角色进行授权,比如:主体的角色为总经理可以查询企业运营报表查询员工工资信息等访问控制流程如下:if(主体.hasRole(总经理角色id)){ 查询工资 }如果上图中查询工资所需要的角色变化为总经理和部门经理此时就需要修改判断逻辑为”判新用户的角也是否是总经理或部门经理”修改代码如下:if(主体.hasRole(总经理角色id)|| 主体.hasRole(部门经理角色id)){ 查询工资 }可以看到如果业务发生变化就需要维护代码扩展性不强。基于资源的访问控制RBAC基于资源的访问控制(Resource-Based AccessControl)是按资源(或权限)进行授权比如:用户必须具有查询工资权限才可以查询员工工资信息等访问控制流程如下:if(主体.hasPermission(查询工资权限标识”)){ 查询工资 }这样不管哪个角色需要查询工资只需要分配一个权限即可只要有权限就可以访问而不用修改代码。代码实现1. 定义Interceptor拦截器拦截请求 这个Bean需要实现 HandlerInterceptor 接口。Component public class SimpleAuthenticationInterceptor implements HandlerInterceptor { 0verride public boolean prelandle(HttpServletRequest request, HttpServletResponse response, 0bject handler) throws Exception { //在这个方法中校验用户请求的u1是否在用户的权限范围内 //取出用户身份信息 Object object request.getSession().getAttribute(UserDto. SESSION USER KEY); if(object nul1){ //没有认证提示登录 writeContex(responsemsg:“请登录”); } UserDto userDto(UserDto) object: //请求的url String requestURI request.getRequestURI(); if(userDto.getAuthorities().contains(p1) requestURl.contains(/r/r1)) { return true; } if(userDto.getAuthorities().contains(p2) requestURl.contains(/r/r2)) { return true; } writeContent(response,权限不足拒绝访问); return false; } //响应信息给客户端 private void writeContent(HttpServletResponse response, String msg)throws IOException { PrintWriter writerresponse.getWriter(); writer.print(msg); writer.close(): } }2. 在WebConfig配置类中注入定义好的拦截器// 注入拦截器 Autowired private SimpleAuthenticationInterceptor simpleAuthenticationInterceptor; Override public void addInterceptors(InterceptorRegistry registry){ registry.addInterceptor(simpleAuthenticationInterceptor) .addPathPatterns(/r/**); // 拦截r开头的请求