SpringBoot - 安全管理框架Spring Security使用1

Java 开发领域常见的安全框架有 Shiro 和 Spring Security ,本文主要讲解Spring Security
一、首先创建springboot项目
创建springboot项目参考https://blog.csdn.net/weixin_40009737/article/details/105773950
在这里插入图片描述

在这里插入图片描述

二、spring security 简介
Spring Security 是一个相对复杂的安全管理框架,功能比 Shiro 更加强大,权限控制细粒度更高,对 OAuth 2 的支持也更友好。
由于 Spring Security 源自 Spring 家族,因此可以和 Spring 框架无缝整合,特别是 Spring Boot 中提供的自动化配置方案,可以让 Spring Security 的使用更加便捷。
spring security 的核心功能主要包括:
认证 (你是谁)
授权 (你能干什么)
攻击防护 (防止伪造身份)
其核心就是一组过滤器链,项目启动后将会自动配置。最核心的就是 Basic Authentication Filter 用来认证用户的身份,一个在spring security中一种过滤器处理一种认证方式。
1.查看pom.xml文件已引入依赖

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

在这里插入图片描述
2.创建一个TestController.java
(1)首先在项目添加一个简单的 /hello 接口:

package com.example.securitydemo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @GetMapping("/hello")
    public String hello() {
        return "欢迎访问 security-demo !";
    }
}

在这里插入图片描述
(2)接着启动项目,直接访问 /hello 接口则会自动跳转到登录页面(这个登录页面是由 Spring Security 提供的)
在这里插入图片描述
(3)我们必须登录后才能访问 /hello 接口。默认用户名是 user,而登录密码则在每次启动项目时随机生成,我们可以在项目启动日志中找到。
在这里插入图片描述
登录之后进入/hello 接口
在这里插入图片描述

3.用户名和密码配置
这个随机生成的密码,每次启动时都会变。对登录的用户名/密码进行配置,有三种不同的方式:

1.在 application.properties 中进行配置
2.通过 Java 代码配置在内存中
3.通过 Java 从数据库中加载
前两种比较简单,第三种代码量略大,本文就先来看看前两种,第三种后面再单独写文章介绍。]

3.1在配置文件 中进行配置用户名/密码
可以直接在 application.properties 文件中配置用户的基本信息:
如果对默认的用户名和密码不满意,可以在 application.properties 中配置默认的用户名、密码和角色。这样项目启动后就不会随机生成密码了,而是使用我们配置的用户、密码,并且登录后还具有一个 admin 角色(关于角色的用法再后面的文章会相信介绍)。

spring.security.user.name=user
spring.security.user.password=1234
spring.security.user.roles=admin

在这里插入图片描述

配置完成后,重启项目,就可以使用这里配置的用户名/密码登录了。
在这里插入图片描述
3.2Java 配置用户名/密码
在这里插入图片描述

(1)我们可以通过自定义类继承 WebSecurityConfigurerAdapter,从而实现对 Spring Security 更多的自定义配置。比如下面样例我们就配置了两个用户,以及他们对应的角色。

基于内存的用户配置在配置角色时不需要添加“ROLE_”前缀
package com.example.securitydemo.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
    // 指定密码的加密方式
    @SuppressWarnings("deprecation")
    @Bean
    PasswordEncoder passwordEncoder(){
        // 不对密码进行加密
        return NoOpPasswordEncoder.getInstance();
    }

    // 配置用户及其对应的角色
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("admin1").password("1234").roles("ADMIN","USER")
                .and()
                .withUser("user1").password("1234").roles("USER");
    }
}

(2)配置完成后,重启项目,就可以使用这两个用户进行登录了。
在这里插入图片描述

在这里插入图片描述
(3)配置 URL 访问权限
1.上面配置完毕后受保护的资源都是默认的(不同角色访问权限也没有什么不同),而真正项目中我们需要根据实际情况进行角色管理。要实现这个功能只需重写 WebSecurityConfigurerAdapter 中的另一个方法即可:

formLogin() 方法表示开启表单登录,即我们之前看到的登录页面。
loginProcessingUrl() 方法配置登录接口为“/login”,即可以直接调用“/login”接口,发起一个 POST 请求进行登录,登录参数中用户名必须为 username,密码必须为 password,配置 loginProcessingUrl 接口主要是方便 Ajax 或者移动端调用登录接口。
permitAll() 表示和登录相关的接口都不需要认证即可访问
package com.example.securitydemo.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
    // 指定密码的加密方式
    @SuppressWarnings("deprecation")
    @Bean
    PasswordEncoder passwordEncoder(){
        // 不对密码进行加密
        return NoOpPasswordEncoder.getInstance();
    }

    // 配置用户及其对应的角色
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("root").password("1234").roles("ADMIN","ROOT")
                .and()
                .withUser("admin1").password("1234").roles("ADMIN","USER")
                .and()
                .withUser("user1").password("1234").roles("USER");
    }

    // 配置 URL 访问权限
    @Override
    protected  void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests() // 开启 HttpSecurity 配置
                .antMatchers("/admin/**").hasRole("ADMIN") // admin/** 模式URL必须具备ADMIN角色
                .antMatchers("/user/**").access("hasAnyRole('ADMIN','USER')") // 该模式需要ADMIN或USER角色
                .antMatchers("/root/**").access("hasRole('ADMIN') and hasRole('ROOT')") // 需ADMIN和DBA角色
                .anyRequest().authenticated() // 用户访问其它URL都必须认证后访问(登录后访问)
                .and().formLogin().loginProcessingUrl("/login").permitAll() // 开启表单登录并配置登录接口
                .and().csrf().disable(); // 关闭csrf
    }
}

2.接着在 Conctoller 中添加如下接口进行测试:

package com.example.securitydemo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @GetMapping("/hello")
    public String hello() {
        return "欢迎访问 security-demo !";
    }
    @GetMapping("/admin/hello")
    public String admin() {
        return "hello admin";
    }

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

    @GetMapping("/root/hello")
    public String db() {
        return "hello root";
    }

}

3.接下来测试一下,我们使用 admin1 用户进行登录,由于该用户具有 ADMIN 和 USER 这两个角色,所以登录后可以访问 /hello、/admin/hello 以及 /user/hello 这三个接口。
在这里插入图片描述
4而由于 /root/hello 接口同时需要 ADMIN 和 DBA 角色,因此 admin1 用户仍然无法访问。
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值