首页 > 其他分享 >6.基于传统的Cookie和Session实现用户的认证授权

6.基于传统的Cookie和Session实现用户的认证授权

时间:2024-05-29 21:21:43浏览次数:17  
标签:String 认证 Session Cookie user test import com public

6.1 概述

  RBAC(Role-Based Access Control,基于角色的访问控制)权限按钮控制是一种细粒度的权限管理方式,它允许系统管理员根据用户的角色来精确控制用户界面中功能按钮的可见性和可用性。在RBAC模型中,权限不仅限于访问某个页面或模块,还可以细化到页面上每个操作按钮的权限。

  前几天以及前段时间一直在思考这个问题,昨天与好友一起讨论了下这个问题,并结合自己在网上查到的资料得以实现。下面给出整个项目代码的重点部分,完整代码如下:

  以下代码借鉴了这篇博客,有兴趣可以查看【认证与授权】2、基于session的认证方式 - 黑米面包派 - 博客园 (cnblogs.com)

6.2 依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ku.test</groupId>
    <artifactId>test-project</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.7.RELEASE</version>
        <relativePath />
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>

</project>

pom.xml
pom.xml

6.3 配置

server.port=8080

6.4 主启动类

package com.ku.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class TestApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
}
主启动类

6.5 用户信息

  为了方便测试这里只是列出了简单的用户名、密码、权限集合等属性

package com.ku.test.entity;

import java.util.Set;

public class User {
    private Integer id;
    private String username;
    private String password;
    private Set<String> auth;

    public User(Integer id, String username, String password, Set<String> auth) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.auth = auth;
    }

    public Integer getId() {
        return id;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public Set<String> getAuth() {
        return auth;
    }
}
用户实体类

6.6 service层

  为了方便测试,并没有使用Mapper从数据库取数据,而是使用Map存储用户信息

package com.ku.test.service;

import com.ku.test.entity.User;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

@Service
public class UserService {
    Map<String, User>userMap = new HashMap<String, User>(){{
        put("xiaoku", new User(1, "xiaoku", "123456",
                new HashSet<String>(){{
                    add("/user/test");
                    add("/user/test1");
                }}
                ));
        put("spring", new User(2, "spring", "123456",
                new HashSet<String>(){{
                    add("/user/test1");
                    add("/user/test2");
                    add("/user/test3");
                    add("/user/test4");
                    add("/user/test5");
                }}
                ));
    }};

    public User getUserByName(String username){
        return userMap.get(username);
    }

    public User auth(String username, String password){
        User user = userMap.get(username);
        if (user == null) throw new RuntimeException("用户不存在!");
        if (!password.equals(user.getPassword())) throw  new RuntimeException("密码错误!");
        return user;
    }
}
UserService

6.7 Controller层

package com.ku.test.controller;

import com.ku.test.common.constant.CommonConstants;
import com.ku.test.entity.User;
import com.ku.test.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/test")
    public String test(){
        return "test";
    }

    @GetMapping("/test1")
    public String test1(){
        //如果请求参数中没有包含HttpServletRequest,则不会被拦截器拦截
        return "test1";
    }

    @PostMapping("/login")
    public String login(HttpServletRequest request){
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        if (request == null || StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) return "用户名或密码为空";
        User user = userService.auth(username, password);
        request.getSession().setAttribute(CommonConstants.USER_SESSION_KET, user);
        return user.getUsername()+"登录成功!";
    }
}
UserController

6.8 配置类

  注册认证授权拦截器,并设置拦截路径和非拦截路径

package com.ku.test.config;

import com.ku.test.interceptor.AuthorizeInterceptor;
import com.ku.test.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //1.添加认证拦截器,并设置拦截路径以及排除路径
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/login");

        //2.添加授权拦截器,并设置拦截路径以及排除路径
        registry.addInterceptor(new AuthorizeInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/login");
    }
}
MVC配置类

6.9 认证授权拦截器

  当用户登录成功后会将用户的信息存储在Session中,认证拦截器实现原理是判断后续请求中Session中是否通过Key获取到的用户是否为空来判断用户是否认证过

package com.ku.test.interceptor;

import com.ku.test.common.constant.CommonConstants;
import com.ku.test.entity.User;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        User user = (User)request.getSession().getAttribute(CommonConstants.USER_SESSION_KET);
        //认证:在拦截器中拦截所有Controller方法的请求,但是排除登录和注册两个请求
        // 当用户注册登录后,如果用户为空则说明未登录,
        if (user != null) return true;
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setContentType("application/json;charset=UTF-8");
        //以字符串返回未登录信息给客户端
        String errorMessage = new String("请先登录!");
        //写入Response返回给客户端
        response.getWriter().write(errorMessage);
        return false;
    }
}

认证拦截器
认证拦截器

  在用户登录后会将用户信息存储在Session中,授权拦截器的实现原理是获取请求的URL与用户信息中的权限集合进行比较,当用户的权限集合包含该路径时,不拦截

package com.ku.test.interceptor;

import com.ku.test.common.constant.CommonConstants;
import com.ku.test.entity.User;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Iterator;
import java.util.Set;

public class AuthorizeInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取该用户的请求路径
        String path = request.getServletPath();
        User user = (User)request.getSession().getAttribute(CommonConstants.USER_SESSION_KET);
        Set<String> auth = user.getAuth();
        boolean successAuthorize = false;
        Iterator<String> iterator = auth.iterator();
        while (iterator.hasNext()){
           if (auth.contains(path)){
               successAuthorize = true;
               break;
           }
           break;
        }
        if (successAuthorize) return true;
        response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
        response.setContentType("application/json;charset=UTF-8");
        //以字符串返回未登录信息给客户端
        String errorMessage = new String("权限不足!");
        //写入Response返回给客户端
        response.getWriter().write(errorMessage);
        return false;
    }
}
授权拦截器

6.10 结果

(1)拥有某方法访问权限的用户

 (2)无某方法访问权限的用户

 

 

标签:String,认证,Session,Cookie,user,test,import,com,public
From: https://www.cnblogs.com/kzf-99/p/18221104

相关文章

  • ClickHouse 留存、路径、漏斗、session 位图 roaringbitmap 位图优化
    Clickhouse在大数据分析平台-留存分析上的应用_大数据_腾讯云大数据_InfoQ写作社区https://xie.infoq.cn/article/c7af40e5ba5f5f5beaccde990ClickHouse实战留存、路径、漏斗、session-腾讯云开发者社区-腾讯云https://cloud.tencent.com/developer/article/1953792导语 | ......
  • AJ-Report 认证绕过与远程代码执行漏洞(CNVD-2024-15077)
    AJ-Report是全开源的一个BI平台。在其1.4.0版本及以前,存在一处认证绕过漏洞,攻击者利用该漏洞可以绕过权限校验并执行任意代码。补丁对比方法一从docker拖出代码,去gitee下载发行版,便于对比编译后的class。方法二查看git的commit记录,可以直接看到修改了哪些内容!后面要去学习......
  • C++语言实现身份证实名认证、身份证上的文字识别接口
    实名认证是什么意思呢?一般指的是对用户资料真实性进行的验证审核,这样有利于建立完善且可靠的互联网环境。如果交易双方使用的都是虚假信息,那么在诸多环节会存在很大的风险。另外,还有游戏平台对玩家进行实名认证,防止未成年人注册。翔云身份证实名认证接口,通过核验身份证二......
  • 虚拟相机一对一聊天平台拍照认证技术永久脚本+【详细教程】
    那么,亲爱的朋友,让我们一起感受这一次的旅程——一次关于虚拟相机、一对一聊天平台的技术故事。这不仅仅是一本教程,更是一本拍照认证技术的启示录,同样也是一段永久脚本的快乐归宿。首先,让我们一起走进虚拟相机的奇幻世界。它不同于传统的硬件设备,而是一种以软件形式存在,能......
  • 绿色革命浪潮来袭!能源管理体系认证,企业转型的秘密武器
    全球对环境保护和可持续发展的日益重视,企业如何实现绿色转型、降低能耗、提升能效,已经成为衡量其竞争力的重要标准。在这一背景下,能源管理体系认证应运而生,成为企业绿色发展的必经之路。1.管理节能新阶段随着全球经济的快速发展,能源短缺已成为制约各国经济发展的主要因素。......
  • 请描述一下 cookies sessionStorage和localstorage区别
    Cookies、sessionStorage和localStorage都是Web浏览器提供的客户端存储机制,但它们之间有一些重要的区别:存储容量:Cookies最大容量约为4KB。sessionStorage和localStorage的容量都约为5MB。有效期:Cookies有明确的过期时间,可以设置为在浏览......
  • pycharm操作push推送失败,提示用户认证失败解决方案
    方法一:首先切换输入法为windows自带,然后切换成英文,输入账户跟密码,尝试再次push,查看是否可以正常push方法二:打开项目文件夹在文件夹右击,点击“Gitbashhere” 打开Gitbash,输入push或pull命令,gitpushorigininsure_gly,切换输入法为windows自带,然后切换成英文,输入账户跟密......
  • 金和OA认证绕过
    https://docs.projectdiscovery.io/templates/reference/matchershttps://furina.org.cn/2023/10/05/Nuclei/https://t.zsxq.com/bIoTf认证绕过+sql注入pocGET/C6/JHSoft.Web.WorkFlat/RssModulesHttp.aspx/?interfaceID=1;WAITFOR%20DELAY%20'0:0:3'--nucleiid:......
  • 婚恋交友系统源码,相亲app源码,相亲交友源码,同城交友,VIP会员,红娘认证,原生源码,免费终身售
    一站式的采购流程,保姆式的技术支持和售后服务售前咨询--专属客服充分了解您的需求、解决疑问、了解产品、明确需求。提供方案--以专业的角度根据您实际情况与需求给予最具性价比、最合适的方案选择。购买产品--一次购买,终身使用,企业化的购买流程,更有保障。安装部署......
  • js怎么保存用户登录信息?js cookie操作封装
    在web开发中,用户登录后需要保存登录信息进行身份识别,登录后的操作都需要带上身份信息请求接口。保存登录信息有多种方法,这里使用cookie进行操作。最终成果:封装cookie操作模块//utils/cookie.jsexportdefault{//设置cookiesetCookie:function(name,value,......