Spring Security OAuth2.0(3):Spring Security简单入门

news2024/11/22 7:24:33

文章目录

  • 前言
  • 一、Spring Security 介绍
  • 二、创建工程
  • 三、认证
    • 1. 认证页面
    • 2. 安全配置
  • 四、授权

前言

Spring Security 快速入门。

本章代码已分享至Gitee:https://gitee.com/lengcz/security-spring-security

一、Spring Security 介绍

\qquad Spring Secutiry 是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。由于它是Spring生态系统的一员,因此它伴随着整个Spring生态系统不断修正、升级,在Springboot项目中加入spring security 更是十分简单,使用Spring Security 减少了为企业系统安全控制编写大量重复代码的工作。

二、创建工程

  1. 创建maven工程(不需要模板)
    在这里插入图片描述

需要创建的目录结构如下
在这里插入图片描述

  1. 导入spring-security的依赖
  <!--spring-security依赖-->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>5.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>5.1.4.RELEASE</version>
        </dependency>

完整的pom文件如下(包含SpringMvc),下内容供参考

<?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.it2</groupId>
    <artifactId>security-spring-security</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.12</version>
        </dependency>

        <!--spring-security依赖-->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>5.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>5.1.4.RELEASE</version>
        </dependency>

    </dependencies>
    <build>
        <finalName>security-springmvc</finalName>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.2</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <configuration>
                        <encoding>utf-8</encoding>
                        <useDefaultDelimiters>true</useDefaultDelimiters>
                        <resources>
                            <resource>
                                <directory>src/main/resources</directory>
                                <filtering>true</filtering>
                                <includes>
                                    <include>**/*</include>
                                </includes>
                            </resource>
                            <resource>
                                <directory>src/main/java</directory>
                                <filtering>true</filtering>
                                <includes>
                                    <include>**/*.xml</include>
                                </includes>
                            </resource>
                        </resources>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

</project>
  1. Spring容器配置
/**
 * config包下定义ApplicationConfig.java,它对应web.xml中ContextLoaderListener的配置
 */
@Configuration  //相当于ApplicationContext.xml
@ComponentScan(basePackages = "com.it2.security.springmvc",
        excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class)})
public class ApplicationConfig {
    //在此配置除了Controller的其它bean,比如:数据库连接池,事务管理器,业务bean等

}
  1. Servlet Context配置
@Configuration //相当于springmvc.xml
@EnableWebMvc
@ComponentScan(basePackages = "com.it2.security",
        includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class)})
public class WebConfig implements WebMvcConfigurer {

    //视图解析器
    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/view/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

    /**
     * spring-scurity 已经包含了权限的拦截器,所以不需要添加权限拦截器
     */
//    @Autowired
//    private SimpleAuthenticationInterceptor simpleAuthenticationInterceptor;
//
//    @Override
//    public void addInterceptors(InterceptorRegistry registry) {
//        registry.addInterceptor(simpleAuthenticationInterceptor).addPathPatterns("/r/**");
//    }
}
  1. 加载Spring容器
    在init包下定义Spring容器初始化类SpringApplicationInitializer,此类实现WebApplicationInitializer接口,Spring容器启动时加载WebApplicationInitializer接口的所有实现类。
public class SpringApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    //spring容器
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{ApplicationConfig.class};
    }

    //servletContext
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }

    //url-mapping
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

三、认证

1. 认证页面

Spring Security 默认提供了认证的页面,不需要额外开发。
在这里插入图片描述

2. 安全配置

spring security 提供了用户名密码登录、退出、会话管理等认证功能,只需要配置即可使用。
(1)在config包下定义WebSecutiryConfig,安全配置的内容包含了用户信息、密码编码器、安全拦截机制。

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


    //定义用户信息服务
    @Bean
    public UserDetailsService userDetailsService() {
        //这里示例使用内存的方式存储用户名、密码和权限
        InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
        inMemoryUserDetailsManager.createUser(User.withUsername("zhangsan").password("111").authorities("p1").build());
        inMemoryUserDetailsManager.createUser(User.withUsername("lisi").password("222").authorities("p2").build());
        return inMemoryUserDetailsManager;
    }

    //密码编码器
    @Bean
    public PasswordEncoder passwordEncoder() { //原文密码比较
        return NoOpPasswordEncoder.getInstance();
    }


    //配置安全拦截机制
    protected void configure(HttpSecurity security) throws Exception {
        security.authorizeRequests()
                .antMatchers("/r/r1").hasAnyAuthority("p1")
                .antMatchers("/r/r2").hasAnyAuthority("p2")
                .antMatchers("/r/**").authenticated() //所有/r/**的请求都必须认证通过
                .anyRequest().permitAll() //除此之外的请求,都可以访问
                .and()
                .formLogin() //允许表单登录
                .successForwardUrl("/login-success");//自定义登录成功后的页面地址

    }

}

在configure中的配置

  • url匹配/r/**的资源,经过认证才可以访问呢
  • 支持form表单认证,认证成功跳转/login-success

(2) 加载WebSecurityConfig
修改SpringApplicationInitializer的getRootConfigClasses()方法,添加WebSecutiryConfig.class

    //spring容器
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{ApplicationConfig.class, WebSecurityConfig.class};
    }

在这里插入图片描述
(3) Spring Security初始化
Spring Security 初始化,这里有两种情况:

  • 若当前环境没有使用Spring或者SpringMVC,则需要将WebSecurity(Spring Secutiry配置类)传入超类,以确保获取配置,并创建spring context。
  • 相反,若当前环境已经加载使用spring,则应该在现有的springcontext中注册Spring Security(上一步已经将WebSecurityConfig加载到 rootcontext),此方法可以什么都不做。
    在init 包下定义SpringSecurityApplicationInitializer
public class SpringSecurityApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

    public SpringSecurityApplicationInitializer() {
//        super(WebSecurityConfig.class);
    }
}

(4) 配置默认根路径跳登录
在WebConfig.java中添加默认请求根路径跳转到/login,此url为spring security提供

  //指向登录页面
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("redirect:/login");//spring-security默认提供的登录页面
    }

(5) 设置登录后跳转的页面

@RestController
@RestController
public class LoginController {


    @RequestMapping(value = "/login-success", produces = "text/plain;charset=utf-8")
    public String login() {
        return "登录成功";
    }

    @RequestMapping(value = "/r/r1", produces = "text/plain;charset=utf-8")
    public String resources1() {
            return "r1资源";
    }

    @RequestMapping(value = "/r/r2", produces = "text/plain;charset=utf-8")
    public String resources2() {
        return "r2资源";
    }

}

在这里插入图片描述
(6)配置启动参数,并启动服务
在这里插入图片描述

如果直接访问/r/r1资源,因为配置了拦截所有请求需要认证,所以它会跳到登录页面。
在这里插入图片描述
如果登录后,在访问/r/r1资源,则没有问题
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

到这里就登录成功了。

(7) 退出
spring security提供了退出的请求,访问/logout即可。
在这里插入图片描述

四、授权

实现授权需要对用户的访问进行拦截校验,校验用户的权限是否可以操作指定的资源,Spring Security默认提供授权实现方法。
签名我们在LoginController添加了/r/r1和/r/r2两个链接的请求资源。

 @RequestMapping(value = "/r/r1", produces = "text/plain;charset=utf-8")
    public String resources1() {
            return "r1资源";
    }

    @RequestMapping(value = "/r/r2", produces = "text/plain;charset=utf-8")
    public String resources2() {
        return "r2资源";
    }

分别配置/r/r1和/r/r2需要的权限

//定义用户信息服务
    @Bean
    public UserDetailsService userDetailsService() {
        //这里示例使用内存的方式存储用户名、密码和权限
        InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
        inMemoryUserDetailsManager.createUser(User.withUsername("zhangsan").password("111").authorities("p1").build());
        inMemoryUserDetailsManager.createUser(User.withUsername("lisi").password("222").authorities("p2").build());
        return inMemoryUserDetailsManager;
    }

    //配置安全拦截机制
    protected void configure(HttpSecurity security) throws Exception {
        security.authorizeRequests()
                .antMatchers("/r/r1").hasAnyAuthority("p1")
                .antMatchers("/r/r2").hasAnyAuthority("p2")
                .antMatchers("/r/**").authenticated() //所有/r/**的请求都必须认证通过
                .anyRequest().permitAll() //除此之外的请求,都可以访问
                .and()
                .formLogin() //允许表单登录
                .successForwardUrl("/login-success");//自定义登录成功后的页面地址

    }

在这里插入图片描述
authorities(a,b,c) 拥有a,b,c的权限
.antMatchers(“/r/r1”).hasAnyAuthority(“p1”,“p3”,“p4”) 访问/r/r1需要p1/p3/p4权限之中任意一个。

启动服务器测试
登录了zhangsan后,分别访问/r/r1和/r/r2请求,可以看到zhangsan只能访问/r/r1,而访问r/r2时显示403 Forbidden,表示zhangsan没有/r/r2的权限。
在这里插入图片描述

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

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

相关文章

vue3中的setup方法

一、vue2中的定义变量和方法的写法 在介绍v3的setup之前&#xff0c;我们先来看看在v2中是如何定义变量和方法的 <template><h2>姓名&#xff1a;{{name}}</h2><h2>年龄&#xff1a;{{age}}</h2><button click"sayHello">说话…

openEuler Linux 光驱开启自动挂载

openEuler Linux 光驱开启自动挂载 创建光驱挂载目录 mkdir -p /mnt/cdrom 手动挂载光驱 但是系统重启后挂载失效 mount /dev/cdrom /mnt/cdrom取消光驱挂载 umount /mnt/cdrom光驱开机自动挂载 临时挂载光驱 mount /dev/cdrom /mnt/cdrom编写配置文件/etc/fstab vi /etc/fst…

【Distributed】分布式监控系统zabbix应用

文章目录 前言一、Zabbix基本概述1. Zabbix 的概念2. Zabbix 的工作原理3. Zabbix 6.0 新特性3.1 Zabbix 可以实现高可用3.2 Zabbix 新增监控系统 4. Zabbix 的构成5. Zabbix 的功能组件5.1 数据库5.2 Web 界面5.3 Zabbix Agent5.4 Zabbix Proxy5.5 Java Gateway 6. Zabbix 和 …

【macOS 系列】如何设置macos的软件、app随系统启动

如何设置app随系统启动 有些app可以在内部实现&#xff0c;如果没有&#xff0c;则需要在系统-偏好设置-用户与群组&#xff0c;切换到登录项&#xff0c;然后在下方可以添加或删除开机启动项。

[管理与领导-6]:新任管理第1课:管理转身--从技术业务走向管理,角色的转变

目录 第1章 管理从转变角色开始 1.1 什么是角色 1.2 角色定位 1.3 技术型与管理型人才差别&#xff1a;六大转变 1.4 不同角色的人能力要求 第2章 管理从定位角色迈步&#xff1a;管理者的四位 2.1 定位 2.1.1 辅助者 2.1.2 教练&#xff1a;以身作则&#xff0c;带领…

【数据结构与算法】树和二叉树课后习题

题目 题目1 知一棵树边的集合为 < I , M > , < I , N > , < E , I > , < B , E > , < B , D > , < A , B > , < G , J > , < G , K > , < C , G > , < C , F > , < H , L > , < C , H > , < A …

财务凭证替代退出类型不正确几个问题汇总

财务凭证替代退出类型不正确几个问题汇总 以上资料均来自网络&#xff0c;纯粹个人工作记录&#xff0c;如有意见请联系删除。 1、两种类型含义 c_exit_param_class. 传参数 代表完全凭证替代 c_exit_param_none. 不传参数 代表行项目替代 exits-name ‘ZFI27’. " …

wpf中DialogResult.Yes方法报错

原因&#xff1a;在WPF里DialogResult没有Yes或No的枚举取值了 所以应该这样写 private void Button_Click(object sender, RoutedEventArgs e) {   if (MessageBox.Show ("要退出程序吗?", "退出程序",MessageBoxButton.YesNo ) MessageBoxResult.Y…

MySQL数据库概述

文章目录 SQL语言的特点SQL的组成部分数据库基本概念数据库性质数据库系统数据库系统的组成部分数据库发展简史 SQL语言的特点 &#xff08;1&#xff09;功能一体化 &#xff08;2&#xff09;高度非过程化 &#xff08;3&#xff09;面向集合的操作方式 &#xff08;4&am…

企业利用bi商业智能工具有哪些改变呢?以瓴羊QuickBI为例

当下的趋势是数字化已经成为一股不可抗拒的力量&#xff0c;推动着全球各国社会经济的发展。在数字经济中&#xff0c;数据是核心基础&#xff0c;包括数据的收集、整合、分析和应用等各个方面。为了充分挖掘数据的价值&#xff0c;各种相关技术近年来得到了迅猛发展。在这些技…

MFC管理系统

文章目录 登录设置登录界面登录用户判断 界面设计嵌入对话框 添加列表添加员工添加按钮 完成添加员工删除员工修改员工信息修改 完成修改员工保存数据打开时显示读取内容全部代码 登录 设置登录界面 初始化窗口实列 添加控件变量 登录用户判断 void CLoginDlg::OnBnClickedB…

C语言程序环境和预处理

本章主要以图片和文字的形式给大家讲解 程序的翻译环境和程序的执行环境 在ANSI C的任何一种实现中&#xff0c;存在两个不同的环境。 第1种是翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令。 第2种是执行环境&#xff0c;它用于实际执行代码 2. 详解编译…

visio常用功能

1.常规对象&#xff0c;鼠标左键操作进行旋转、下图旋转柄是鼠标左键拖动可以任意改变方向&#xff0c;改变大小&#xff08;长度、宽度、等比例&#xff09;。 2.注意&#xff1a;用大小和位置定量改变形状的大小和角度 在选中形状对象后&#xff0c;页面底部会出现该形状的大…

【Spring Boot】Spring Boot日志详情:基于lombok的日志输出

文章目录 1. 何为日志文件&#xff1f;2. 日志文件的作用3. 日志文件的基本使用3.1 Spring Boot中的日志3.2 自定义日志打印 4 日志级别4.1 日志级别的作用4.2 日志级别的分类4.3 日志级别的设置 5 日志持久化6 基于lombok的日志输出6.1 lombok 简单输出日志案例6.2 浅谈 lombo…

如果遇到洪灾导致网络瘫痪,对讲机能起到什么作用?

当我们遇到洪灾这种突发事件时&#xff0c;网络基本就会处于瘫痪状态&#xff0c;人们的安全和生命也将面临着极大的威胁。而在这种时候&#xff0c;一种看似普通的通讯工具&#xff0c;却能够成为拯救生命的关键&#xff0c;它就是——对讲机&#xff01; 网络已经成为我们生…

使用3D Slicer进行图像配准

在3D Slicer官网上&#xff08;https://www.slicer.org/&#xff09;下载最新版本的软件 下载完成后按照指示安装软件&#xff0c;并在安装目录下打开软件 打开后在插件市场搜索并安装需要的配准插件 安装完成后重新打开软件&#xff0c;进行图像配准操作&#xff0c;首先需…

FreeRTOS ~(四)同步互斥与通信 ~ (1/3)同步的缺陷

举例子说明&#xff1a;同步的缺陷 首先创建两个任务&#xff1a;Task1和Task2; 让Task1执行一个比较耗时的计算,计算完成之后,通知Task2; Task1&#xff1a;求和,sum,累加10000000次,然后标志位置1 Task2&#xff1a;检测到标志位置1,打印sum值 为了可以在逻辑分析仪上更准确…

Kibana的对索引库的操作(2)

使用Kibana对文档操作 1.新增文档 新增文档并随机生成id: POST /索引库名/类型名{"key","value"} 新增文档并自定义id:POST /索引库名/类型名/id值 {"key","value"} 2.查看文档 如果查询的文档不存在则返回false 3.修改文档 这里需…

【Telephony】SIM单卡到双卡的变化

1、注册观察者 --> PhoneFactory.makeDefaultPhones() --> TelephonyComponentFactory.makeSubscriptionInfoUpdater() --> new SubscriptionInfoUpdater() --> PhoneConfigurationManager.registerForMultiSimConfigChange(this, EVENT_MULTI_SIM_CONFIG_CHAN…

linux下载安装jdk

1、一般linux系统会自带jdk&#xff0c;执行搜索命令&#xff0c;会查询到不同版本jdk。 2、执行yum install java-1.8.0-openjdk 命令下载对应版本jdk 3、java -version 验证