8.Spring Security 权限控制

news2025/1/15 6:36:28

1.简介入门

JavaEE和SpringMVC :Spring Security就是通过11个Fliter进行组合管理

小Demo

user实体类

  • user.type字段,0普通用户,1超级管理员,2版主

  • 补全get set tostring

  • implement UserDetails,重写以下方法

// true: 账号未过期.
@Override
public boolean isAccountNonExpired() {
    return true;
}

// true: 账号未锁定.
@Override
public boolean isAccountNonLocked() {
    return true;
}

// true: 凭证未过期.
@Override
public boolean isCredentialsNonExpired() {
    return true;
}

// true: 账号可用.
@Override
public boolean isEnabled() {
    return true;
}

//获取当前用户权限列表
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    List<GrantedAuthority> list = new ArrayList<>();
    list.add(new GrantedAuthority() {
        @Override
        public String getAuthority() {
            switch (type) {
                case 1:
                    return "ADMIN";
                default:
                    return "USER";
            }
        }
    });
    return list;
}

UserService

unservice implement UserDetailsService

  • 重写方法loadUserByUsername

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    return this.findUserByName(username);
}

SecurityConfig 配置类

  • extend父类WebSecurityConfigurerAdapter

  • 注入UserService

  • 重写configure(WebSecurity web),忽略静态资源的访

@Override
public void configure(WebSecurity web) throws Exception {
    // 忽略静态资源的访问
    web.ignoring().antMatchers("/resources/**");
}
  • 重写configure(AuthenticationManagerBuilder auth),这个方法主要是做认证。

  • AuthenticationManager: 认证的核心接口

  • AuthenticationManagerBuilder: 用于构建AuthenticationManager对象的工具

  • ProviderManager: AuthenticationManager接口的默认实现类

  • ProviderManager--一组-->AuthenticationProvider--每个负责-->一种认证

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    // 内置的认证规则
    // auth.userDetailsService(userService).passwordEncoder(new Pbkdf2PasswordEncoder("12345"));

    // 自定义认证规则
    // AuthenticationProvider: ProviderManager持有一组AuthenticationProvider,每个AuthenticationProvider负责一种认证.
    // 委托模式: ProviderManager将认证委托给AuthenticationProvider.
    auth.authenticationProvider(new AuthenticationProvider() {
        // Authentication: 用于封装认证信息的接口,不同的实现类代表不同类型的认证信息.
        @Override
        public Authentication authenticate(Authentication authentication) throws AuthenticationException {
            String username = authentication.getName();
            String password = (String) authentication.getCredentials();

            User user = userService.findUserByName(username);
            if (user == null) {
                throw new UsernameNotFoundException("账号不存在!");
            }

            password = CommunityUtil.md5(password + user.getSalt());
            if (!user.getPassword().equals(password)) {
                throw new BadCredentialsException("密码不正确!");
            }

            // principal: 主要信息; credentials: 证书; authorities: 权限;
            return new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());
        }

        // 当前的AuthenticationProvider支持哪种类型的认证.
        @Override
        public boolean supports(Class<?> aClass) {
            // UsernamePasswordAuthenticationToken: Authentication接口的常用的实现类.
            return UsernamePasswordAuthenticationToken.class.equals(aClass);
        }
    });
}
  • 重写configure(HttpSecurity http)

配置登陆页面http.formLogin()

登录成功处理器.successHandler

登录失败处理器.failureHandler

退出相关配置http.logout()

授权配置http.authorizeRequests()

验证码在验证账号之前

 @Override
protected void configure(HttpSecurity http) throws Exception {
    // 登录相关配置
    http.formLogin()
            .loginPage("/loginpage")
            .loginProcessingUrl("/login")
            .successHandler(new AuthenticationSuccessHandler() {
                @Override
                public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                    response.sendRedirect(request.getContextPath() + "/index");
                }
            })
            .failureHandler(new AuthenticationFailureHandler() {
                @Override
                public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
                    request.setAttribute("error", e.getMessage());
                    request.getRequestDispatcher("/loginpage").forward(request, response);
                }
            });

    // 退出相关配置
    http.logout()
            .logoutUrl("/logout")
            .logoutSuccessHandler(new LogoutSuccessHandler() {
                @Override
                public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                    response.sendRedirect(request.getContextPath() + "/index");
                }
            });

    // 授权配置
    http.authorizeRequests()
            .antMatchers("/letter").hasAnyAuthority("USER", "ADMIN")
            .antMatchers("/admin").hasAnyAuthority("ADMIN")
            .and().exceptionHandling().accessDeniedPage("/denied");

    // 增加Filter,处理验证码
    http.addFilterBefore(new Filter() {
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            if (request.getServletPath().equals("/login")) {
                String verifyCode = request.getParameter("verifyCode");
                if (verifyCode == null || !verifyCode.equalsIgnoreCase("1234")) {
                    request.setAttribute("error", "验证码错误!");
                    request.getRequestDispatcher("/loginpage").forward(request, response);//转发
                    return;
                }
            }
            // 让请求继续向下执行.
            filterChain.doFilter(request, response);
        }
    }, UsernamePasswordAuthenticationFilter.class);

    // 记住我
    http.rememberMe()
            .tokenRepository(new InMemoryTokenRepositoryImpl())
            .tokenValiditySeconds(3600 * 24)
            .userDetailsService(userService);

}

HomeController

在首页添加欢迎信息,通过SecurityContextHolder获取登陆者信息

@RequestMapping(path = "/index", method = RequestMethod.GET)
public String getIndexPage(Model model) {
    // 认证成功后,结果会通过SecurityContextHolder存入SecurityContext中.
    Object obj = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    if (obj instanceof User) {
        model.addAttribute("loginUser", obj);
    }
    return "/index";
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/372394.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

_improve-2

-------------------- 左边定宽&#xff0c;右边自适应方案 float margin&#xff0c;float calc /* 方案1 */ .left {width: 120px;float: left; } .right {margin-left: 120px; } /* 方案2 */ .left {width: 120px;float: left; } .right {width: calc(100% - 120px);fl…

【深度学习】线性回归、逻辑回归、二分类,多分类等基础知识总结

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言1. 线性回归2、逻辑回归3. 单层神经元的缺陷&多层感知机softmax 多分类前言 入行深度学习快2年了,是时间好好总结下基础知识了.现在看可能很多结论和刚学的…

SystemVerilog-时序逻辑建模(5)多个时钟和时钟域交叉

数字硬件建模SystemVerilog-时序逻辑建模&#xff08;5&#xff09;多个时钟和时钟域交叉数字门级电路可分为两大类&#xff1a;组合逻辑和时序逻辑。锁存器是组合逻辑和时序逻辑的一个交叉点&#xff0c;在后面会作为单独的主题处理。组合逻辑描述了门级电路&#xff0c;其中逻…

办公室人员离岗识别检测系统 yolov7

办公室人员离岗识别检测系统根据yolov7网络模型深度学习技术&#xff0c;办公室人员离岗识别检测算法能够7*24小时全天候自动识别人员是否在岗位。YOLOv7 在 5 FPS 到 160 FPS 范围内&#xff0c;速度和精度都超过了所有已知的目标检测器&#xff0c;并在V100 上&#xff0c;30…

2023/2/26 Vue学习笔记 配置代理解决跨域[CORS ]的问题

利用vue的脚手架巧妙的解决ajax跨域的问题 1 我们首先利用springboot服务搭建 注意这里引出了跨域[CORS ]的问题: Access to XMLHttpRequest at http://localhost:5000/getUserInfo from origin http://localhost:8080 has been blocked by CORS policy: No Access-Control-A…

【Java】Spring Boot 2 集成 nacos

【Java】Spring Boot 2 集成 nacos 官方文档&#xff1a;https://nacos.io/zh-cn/docs/quick-start-spring-boot.html pom 本次Springboot版本 2.2.6.RELEASE&#xff0c;nacos-config 版本 0.2.7&#xff0c;nacos-discovery版本 0.2.7 parent <parent><groupId&…

带你深层了解c语言指针

前言 &#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&#x1f32f; c语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f349;本篇简介:>:介绍c语言中有关指针更深层的知识. 金句分享: ✨今天…

麻省理工学院,Web3 人才辈出

2 月 22 日&#xff0c;NFT 交易平台 Blur 创始人公开身份&#xff0c;曾就读于麻省理工学院计算机系。除了 NFT 交易平台&#xff0c;在公链、交易所、VC、媒体、Layer2 等 Web3 和 Crypto 的多个赛道&#xff0c;麻省理工学院&#xff08;MIT&#xff09;的毕业生和教授们均有…

HDMI协议介绍(二)--DataIsland Packets

前言 前文简单介绍了HDMI传输的三个周期&#xff1a;控制周期、DataIsland周期和Video周期。DataIsland传输音频和辅助数据&#xff0c;这些数据以Packet的形式传输。本文简单介绍DataIsland Packet。 目录 前言 数据岛概述 数据岛包的构造 Packet Header Paket Body Dat…

从0开始学python -40

Python3 面向对象-3 类属性与方法 类的私有属性 __private_attrs &#xff1a;两个下划线开头&#xff0c;声明该属性为私有&#xff0c;不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs 。 类的方法 在类的内部&#xff0c;使用 def 关键字…

Linux驱动——设备模型

目录 一、起源 二、新方案 2.1 sysfs: 2.2 uevent 三、代码中自动mknod 四、实例 一、起源 仅devfs&#xff0c;导致开发不方便以及一些功能难以支持&#xff1a;&#xff08;硬编&#xff09; 1. 热插拔&#xff08;插上usb设备就立马能安装驱动&#xff09; 2. 不支持…

蓝桥杯2015年第六届真题-奇怪的数列C++

题目&#xff1a;从X星截获一份电码&#xff0c;是一些数字&#xff0c;如下&#xff1a;13111331131321131113122113....YY博士经彻夜研究&#xff0c;发现了规律&#xff1a;第一行的数字随便是什么&#xff0c;以后每一行都是对上一行“读出来”比如第2行&#xff0c;是对第…

hadoop网站流量日志数据统计

系统背景介绍 数据提供企业决策能力 网站日志的数据分析------》受欢迎程度如何评价你这个网站的受欢迎程度 用数据 下载的人多了 观看的人多了 通过Hadoop 对某个网站产生的日志数据流量进行统计分析 得出该网站的访问流量 继而做出决策我们可以采用flume收集nginx的success文…

AcWing算法提高课-2.1.1池塘计数

宣传一下算法提高课整理 <— CSDN个人主页&#xff1a;更好的阅读体验 <— 题目传送门点这里 题目描述 农夫约翰有一片 N∗M 的矩形土地。 最近&#xff0c;由于降雨的原因&#xff0c;部分土地被水淹没了。 现在用一个字符矩阵来表示他的土地。 每个单元格内&…

EasyRecovery16最新免费版电脑数据恢复软件功能介绍

EasyRecovery是一款支持Windows/Mac平台进行恢复图片的专业工具&#xff0c;尤其是各种流行单反相机RAW格式文件&#xff0c;以及超大型视频文件等&#xff0c;推荐摄影爱好者使用。适用于主流相机、无人机、PC、存储卡、USB 闪存驱动器等&#xff0c;由于删除、损坏或意外格式…

【项目精选】医院管理住院系统的研究与实现(源码+论文+视频)

点击下载源码 本系统主要分为六大模块&#xff0c;分别是医生管理模块、病人管理模块、病床管理模块、收费管理模块、统计分析模块和系统功能模块 &#xff0c;医生、病人和医院的管理人员都可以通过此系统寻找出自己所需要的信息。 1.1 背景 医院管理住院系统是当今大部分现代…

Nginx安装及介绍

前言&#xff1a;传统结构上(如下图所示)我们只会部署一台服务器用来跑服务&#xff0c;在并发量小&#xff0c;用户访问少的情况下基本够用但随着用户访问的越来越多&#xff0c;并发量慢慢增多了&#xff0c;这时候一台服务器已经不能满足我们了&#xff0c;需要我们增加服务…

华为OD机试用Python实现 -【天然蓄水库 or 天然蓄水池】(2023-Q1 新题)

华为OD机试题 华为OD机试300题大纲天然蓄水库 or 天然蓄水池题目描述输入描述输出描述说明示例一输入输出说明示例二输入输出说明示例三输入输出说明Python 代码实现算法思路华为OD机试300题大纲 参加华为

Android 分区和内存监控

Andorid之所以是分区&#xff0c;是因为各自有对应的功能和用途的考量&#xff0c;可以进行单独读写和格式化。Android 设备包含两类分区&#xff1a;一类是启动分区&#xff0c;对启动过程至关重要。一类是用户分区&#xff0c;用于存储与启动无关的信息。启动分区boot 分区一…

HTML综合案例练习

一、展示简历内容 可以首先看一下我们的效果&#xff0c;之后再思考怎么实现 总的来说&#xff0c;这个练习不算难。 这里关于这个简历的代码编写我们不说太多&#xff0c;只注意以下几个内容即可&#xff1a; 注意及时查看我们的代码是否符合预期&#xff0c;即一段一段测 …