我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Spring Security入门demo案例

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Spring Security入门demo案例

一、简介

Spring Security是一个高度自定义的安全框架。利用Spring IoC/DI和AOP功能,为系统提供了声明式安全访问控制功能,减少了为系统安全而编写大量重复代码的工作。主要包含如下几个重要的内容:

  • 认证(Authentication),系统认为用户是否能登录。
  • 授权(Authorization),系统判断用户是否有权限去做某些事情。

二、入门案例

首先引入必要的依赖:


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

然后创建一个controller:


@Slf4j
@RestController
public class SecurityController {

    @GetMapping({"/", "/index"})
    public String getLogin() {
        log.info("进入index");
        return "index";
    }

}

此时,我们的入门案例就完成了。启动项目,Spring Security默认就开启了,此时访问localhost:8080/index就会被Spring Security拦截,跳转到内置的登录页面要求登录。

默认情况下,登录的用户名为user,密码在启动项目的时候,控制台有打印出来:

Using generated security password: 0bfad04b-7a47-40fb-ae15-2a4a7c57099b

使用如上的账密登录后,再次访问localhost:8080/index就可以正常返回预期的内容index了。

如果我们不希望使用默认的用户密码,可以在配置文件中指定一个,如此Spring Security就会使用我们指定的,而不会使用默认的了。


spring.security.user.name=zhangxun
spring.security.user.password=123123

三、自定义认证逻辑

当我们开启自定义认证逻辑后,上面的默认用户和配置文件中的用户就不生效了,可以先行删除。

我们新建一个MySecurityConfig类,并继承WebSecurityConfigurerAdapter类,用于自定义认证逻辑。


@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 指定使用BCryptPasswordEncoder对前端传过来的明文密码进行encode
        PasswordEncoder encoder = new BCryptPasswordEncoder();
        // 用户的真实密码需要encode,security是比较两个密文是否一致
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("root").password(encoder.encode("root123")).roles();
    }

}

需要注意的是,密码必须使用如上的PasswordEncoder进行编码,否则会抛出如下错误:

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"

此时,我们重启应用,访问localhost:8080/index进入内置的登录页面,输入root/root123之后就能正常返回index内容了。

四、自定义授权逻辑

一般权限管理都是基于RBAC模型的,即登录的用户肯定拥有某些角色,这些角色允许访问某些资源。我们先来改造下认证的逻辑:


@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    PasswordEncoder encoder = new BCryptPasswordEncoder();
    auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
        .withUser("root").password(encoder.encode("root123")).roles("admin","manager")
        .and()
        .withUser("manager").password(encoder.encode("mm000")).roles("manager");
}

使得root用户拥有admin和manager两个角色,zhang用户拥有manager一个角色。

然后我们在该配置类中再增加自定义授权的逻辑:


@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        // 任何角色允许访问
        .antMatchers("/", "/index").permitAll()
        // 仅admin角色可以访问
        .antMatchers("/admin/**").hasRole("admin")
        // admin和manager两个角色可以访问
        .antMatchers("/manager/**").hasAnyRole("admin", "manager");

    // 没有权限则进入内置的登录页面
    http.formLogin();
}

然后为了测试,我们还需要增加几个资源:


@Slf4j
@RestController
public class SecurityController {

    @GetMapping({"/", "/index"})
    public String getLogin() {
        log.info("进入index");
        return "index";
    }

    @GetMapping("admin/getHello")
    public String getAdminHello(){
        return "hello admin!";
    }

    @GetMapping("manager/getHello")
    public String getManagerHello(){
        return "hello manager!";
    }

    @GetMapping("guest/getHello")
    public String getGuestHello(){
        return "hello guest!";
    }

}

此时,重启项目,我们发现:

  • 访问/,/index,/guest/**的资源直接就能返回,不需要认证和授权。
  • 访问/admin/**资源的时候,由于没有登录,会跳转到内置的登录页面;如果已经登录,只有root用户登录后才可以访问;
  • 访问/admin/**资源的时候,由于没有登录,会跳转到内置的登录页面;如果已经登录,那么root和zhang用户都能访问;

我们还可以定制自己的登录页面,用于替换Spring Security内置的登录页面,这块需要定制html页面,本文不再详述,比较简单,可以参考formLogin的源码注释,里面讲的比较清楚。

五、注销登录

因为我们使用的是Spring Security内置的登录页面,各个资源返回的也是json字符串,并非页面,所以如何实现注销登录是个问题。但可以通过阅读HttpSecurity:logout中的源码注释,我们基本就能学会怎么操作了。

  • 注销登录默认就开启了,默认是访问/logout,和/login一样都是Spring Security自己实现的,我们调用即可;
  • 注销登录会清除服务器端的session,清除remember me等设置;这个后面再详细解说;
  • 注销登录后默认会跳转到/login页面;

还是如上的案例,我们在登录后,直接调用http://localhost:8080/logout就可以实现上述的注销登录功能了。

但是在有些时候,我们会自定义登出的URL以及成功登出后应该跳转到哪个URL,Spring Security也支持我们进行自定义。


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 任何角色允许访问
                .antMatchers("/", "/index").permitAll()
                // 仅admin角色可以访问
                .antMatchers("/admin/**").hasRole("admin")
                // admin和manager两个角色可以访问
                .antMatchers("/manager/**").hasAnyRole("admin", "manager");

        // 没有权限进入内置的登录页面
        http.formLogin();
        // 自定义登出逻辑
        http.logout().logoutUrl("/myLogOut").logoutSuccessUrl("/index");
    }

当Post方式请求/myLogOut的时候就会触发Spring Security的登出逻辑,并且登出后会跳转到/index界面。

注意:在本案例中,是使用浏览器进行测试的,而且没有html的页面,所以使用浏览器发起post请求比较困难,那么使用get请求发起可以吗?默认是不行的,因为Spring Security默认开启了CSRF校验,所有改变状态的请求都必须以POST方式提交,为了能验证我们这个例子,我们需要把CSRF校验关掉,即在如上logout代码后面加上如下的配置:


// 暂时关闭CSRF校验,允许get请求登出
http.csrf().disable();

此时再重启应用,就可以验证localhost:8080/myLogOut的登出逻辑了。

六、记住我功能

当我们没有开启记住我功能的时候,登录root用户后,如果关掉浏览器,重新打开网址,会发现登录已经退出了,这是因为登录信息只在当前会话有效。

如果我们想要在某个时间段以内,一直使root用户处于登录状态,那么就需要在浏览器端设置一个cookie,在有效期内,这个cookie所属的用户就一直是登录的状态。同样的,只要在上面注销登录的代码后面加上:


// 开启remember me功能,有效期默认14天
http.rememberMe();

此时内置的登录页面会出现记住我的选择框,当我们选择上登录后,浏览器端就会有当前用户的cookie信息了(名称为remember-me),在它过期之前,登录状态就一直有效。

需要用户主动退出登录,也就是调用我们上面的/myLogOut才能将cookie清除并退出登录。

如果是自定义的登录页面,可以在后面链式调用rememberMeParameter()方法,传入自己的rememberme参数名称即可。

以上是关于Spring Security的基本使用方法,使用数据库及其它特性将会在后面的文章中予以说明。

七、会话管理

在以上例子中,认证和授权都是Spring Security自动进行的。但是有的时候我们需要管理会话,比如从会话中获取用户姓名、用户的权限信息;会话策略选择以及会话超时设置等。

我们只需要增加如下的方法即可:


    private String getName(){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Object principal = authentication.getPrincipal();
        if(principal == null){
            return "游客";
        }
        if(principal instanceof UserDetails){
            UserDetails userDetails = (UserDetails) principal;
            return userDetails.getUsername();
        } else{
            return principal.toString();
        }
    }

该方法使用SecurityContextHolder获取上下文信息,然后再获取到其中的用户名即可,当然其中还提供了可以获取密码、权限信息等方法。

Session的管理策略有以下几种:

  • always,如果没有Session就会创建一个;
  • ifRequired,登录时如果有需要,就创建一个;
  • never,不会主动创建session,如果其它地方创建了session,就会使用它;
  • stateless,不会创建也不会使用session;

其中ifRequired是默认的模式,stateless是采用token机制时,session禁用的模式,设置方法如下:


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
    }

至于session的超时和安全可以在配置文件中设置:


# 超时时间设置
server.servlet.session.timeout=3600s
# 浏览器脚本将无法访问cookie
server.servlet.session.cookie.http‐only=true
# cookie将仅通过HTTPS连接发送
server.servlet.session.cookie.secure=true

到此这篇关于Spring Security入门demo案例的文章就介绍到这了,更多相关Spring Security入门内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Spring Security入门demo案例

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

typescript在vue中的入门案例代码demo

这篇文章主要介绍了typescript在vue中的入门案例代码demo,使用技术栈vue2+typescript+scss入门练手项目,天气预报demo,需要的朋友可以参考下。
2022-12-30

轻松入门Java Spring Boot Security:全面指南

Java Spring Boot Security是一个强大且易于使用的库,用于在Java Spring Boot应用程序中保护资源。它提供开箱即用的安全性功能,例如身份验证、授权和防伪造请求。本文将提供一个全面的指南,帮助您轻松入门使用Java Spring Boot Security。
轻松入门Java Spring Boot Security:全面指南
2024-02-02

Python入门(案例)

#一.上课案例:#输出hello wordprint('hello word')#python注释有两种#1.单行注释#这是单行注释#2.多行注释'''这是多行注释'''#python变量name='liuyongqi'age=18prin
2023-01-30

hibernate+spring入门实例

hibernate+spring基础整合入门*****************************************映射数据库表 Users.javapackage com.hs.bean;public class Users
2023-06-03

drools入门案例分析

今天小编给大家分享一下drools入门案例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、背景最近在学习规则引擎dro
2023-06-30

Python入门经典案例一

# 有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?1 sum = 02 values = range(1, 5)3 for i in values:4 for j in values:5
2023-01-30

c++连接mysql入门案例

这篇文章主要介绍了c++连接mysql入门案例,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-11-16

spring中bean实例化的三种方式 -- Spring入门(二)

文章目录 前言1.Bean实例化简介2.bean的实例化 -- 构造方法3.bean的实例化 -- 静态工厂实例化4.bean实例化 -- 实例工厂和FactoryBean5.三种bean实例化方式的区别 总结 前言 为了
2023-08-19

Java注解入门案例代码分析

这篇文章主要介绍“Java注解入门案例代码分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java注解入门案例代码分析”文章能帮助大家解决问题。Talk is cheap, show me the
2023-07-05

Java注解的简单入门小案例

这篇文章主要介绍了Java注解的简单入门小案例,注解是干什么的?怎么使用?注解的简单用法,需要的朋友可以参考下
2023-05-14

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录