当前位置:   article > 正文

SpringSecurity安全授权,2024最新网络安全面试笔试题目分享

SpringSecurity安全授权,2024最新网络安全面试笔试题目分享

7.多种角色权限认证

8.自定义权限认证与注解方式认证

9. SpringSecurity认证授权流程分析(总)

总结


前言

安全对于任何系统来说都是非常重要的,权限的分配和管理一直都是开发者需要特别重视的。一旦缺乏基本和有力的授权验证,一些别有用心之人就会利用这个漏洞对开发者的 Web 应用或者其他软件进行不法侵害。Spring Boot 技术中有许多优秀的安全框架和认证授权方案,本次将介绍比较流行的框架技术 Spring Security 及其实践应用。


正文

Spring Security 是 Spring Boot 中一款功能强大基于 Spring 的企业级应用的提供安全访问权限的安装框架,在实际工程项目中也会经常用到。通过依赖注入的方式,可以使用 Spring Security 库提供声明式的安全访问控制功能。它和 Spring Boot 以及其他 Spring 模块紧密相连。

1.基本流程

Spring Security 的原理其实就是一个过滤器链,内部包含了提供各种功能的过滤器

图中只展示了核心过滤器,其它的非核心过滤器并没有在图中展示

  • UsernamePasswordAuthenticationFilter:负责处理我们在登页面填写了用户名密码后的登陆请求。入门案例的认证工作主要有它负责。
  • ExceptionTranslationFilter: 外理过滤器中抛出的任 AccessDeniedException 和 AuthenticationException。
  • FilterSecuritylnterceptor: 负责权限校验的过滤器

通过 debug 查看当前的过滤器链

package org.example;

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

@SpringBootApplication
public class Main {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(Main.class, args);
System.out.println(run);//在此处打上断点
}
}

打开表达式计算面板

run.getBean(DefaultSecurityFilterChain.class)

计算求值:

  • SecurityContextPersistenceFilter 这个Filter是整个拦截过程的入口和出口(也就是第一个最后一个拦截器),会在请求开始时从配置好的 SecurityContextRepository 中获取SecurityContext,然后把它设置给 SecurityContextHolder。在请求完成后将SecurityContextHolder 持有的 SecurityContext 再保存到配置好的SecurityContextRepository,同时清除 securityContextHolder 所持有的 SecurityContext;
  • SecurityContext 的内部是 ThreadLocal 存储权限信息,由于过滤器链中的对象都需要权限信息进行过滤操作,如果以传递的方式维护成本很高,所以使用安全上下文。任意方法都可以使用下面的操作获取权限上下文信息。

SecurityContextHolder.getContext();

2.基本用法

安装,在 pom.xml 中导入依赖即可

org.springframework.boot spring-boot-starter-security

在项目中编写一个测试的接口 /testHi,代码如下:

package org.example.controller;

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

@RestController
public class HiController {
@GetMapping(“/hi”)
public String hi(){
return “Hi”;
}
}

编写一个类,更好的配置管理。

package org.example.config;

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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**

  • Security 配置类
    /
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /
    *
  • 认证
  • @param auth
  • @throws Exception
    */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
    .passwordEncoder(new BCryptPasswordEncoder())
    .withUser(“freejava”)
    .password(new BCryptPasswordEncoder().encode(“123456”))
    .roles(“VIP1”);
    }

/**

  • 授权
  • @param http
  • @throws Exception
    */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    //设置匹配的资源白名单访问
    http.authorizeRequests().antMatchers(“/”,“/asserts/“,
    “/pages/login.html”,”/userlogin")
    .permitAll()
    .antMatchers("/level1/
    ”).hasRole(“VIP1”)
    .antMatchers(“/level2/“).hasRole(“VIP2”)
    .antMatchers(”/level3/
    ”).hasRole(“VIP3”)
    .anyRequest().authenticated();//剩余任何资源必须认证
    //开启登录页
    http.formLogin();
    //开启自动注销
    http.logout().logoutSuccessUrl(“/login”);//注销之后来到登录页
    http.csrf().disable();
    }
    }

最后运行会出现如下界面:

3.配置项

如果想要修改默认的账号和密码,可以在 application.properties 文件中加入下面的配置项。

spring.security.user.name=freejava
spring.security.user.password=123456
spring.security.user.roles[]=admin

4.HttpSecurity 方式和内存认证方式

所谓内存认证就是自定义配置类,该配置类继承 WebSecurityConfigurerAdapter,需要实现一些自定义配置和方法,具体代码如下:

package org.example.config;

import org.springframework.beans.factory.annotation.Autowired;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@EnableWebSecurity
public class RealSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
PasswordEncoder passwordEncoder(){
//NoOpPasswordEncoder 在高版本的Spring Boot 中已被弃用,不建议使用
return new BCryptPasswordEncoder();
}

@Autowired PasswordEncoder passwordEncoder;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder)//使用对应的加密
.withUser(“admin”)
.password(passwordEncoder.encode(“123456”))//使用对应的解密
.roles(“ADMIN”,“USER”)
.and()
.withUser(“freephp”)
.password(passwordEncoder.encode(“123456”))
.roles(“USER”);
}
}

上面这段代码中,inMemoryAuthentication 代表把这个配置保存在内存中,然后使用 withUser 方法增加授权账号,用 password 方法设置密码,用 roles 来设置账号所属的权限群组。

HttpSecurity 是另外一种认证方式,也是使用 configure 方法,具体代码如下:

@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(“/admin/“)
.hasRole(“ADMIN”)
.antMatchers(”/user/
”)
.access(“hasAnyRole(‘ADMIN’,‘USER’)”)
.anyRequest()
.authenticated()//任意登录的用户都可以访问
.and()
.formLogin()
.loginProcessingUrl(“/login”)
.permitAll()
.and()
.csrf()
.disable();
}

使用 andMatcher 设置需要被授权的 URL 路径,access 方法给予某些角色访问权限,代码如下:。

package org.example.controller;

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

@RestController
public class SwagController {
@GetMapping(“/user/sayHi”)
public String myUser(){
return “Hi,user”;
}

@GetMapping(“/admin/hello”)
public String admin(){
return “admin page”;
}

@GetMapping(“/hello”)
public String hello(){
return “hello,man”;
}
}

运行项目后,访问 http://localhost:8080/admin/hello, 则会要求输入账号和密码,使用 admin 账号,密码输入 123456,即可进入后台 /admin/hello 页面,如图。

5.认证流程

  • Authentication接口: 它的实现类,表示当前访问系统的用户,封装了用户相关信息。
  • AuthenticationManager接口: 定义了认证Authentication的方法。
  • UserDetailsService接口: 加载用户特定数据的核心接口。里面定义了一个根据用户名查询用户信息的方法。
  • UserDetails接口: 提供核心用户信息。通过UserDetailsService根据用户名获取处理的用户信息要封装成UserDetails对象返回,然后将这些信息封装到Authentication对象中。

所以接下来如果要使用数据库做登录验证,只要把实现类 InMemoryUserDetailsManager 做一个替换,DaoAuthenticationProvider 调用自定义的实现类。让其不再使用内存做认证进入数据库查询,实现 UserDetailsService 接口即可。

6.基于数据库查询的登录验证

之前都是使用内存来存储认证数据,其实可以考虑使用数据库进行持久化数据存储。这样更加方便进行账号管理,也更符合实际项目开发的需求。

创建一个 roles 库,然后创建用户表、角色权限表、用户和角色权限关系表。

create database r_security;
use r_security;
– 用户表
CREATE TABLE r_users(
id int(11) unsigned NOT NULL AUTO_INCREMENT primary key COMMENT ‘主键’,
username varchar(50) not null comment ‘账号名’,
password varchar(300) not null comment ‘密码’,
status tinyint(11) not null comment ‘账号状态,1:正常、2:被封’,
created int (11) not null comment ‘创建时间,时间戳’
);
– 角色权限表
create table r_roles(
id int(11) unsigned not null auto_increment comment ‘主键’,
name varchar(50) not null comment ‘角色名’,
permission_path varchar(500) not null comment ‘权限路径,如/admin/*’,
primary key (id)
);
– 用户角色权限关系表
create table r_user_roles(
id int(11) unsigned not null auto_increment comment ‘主键’,
user_id int(11) unsigned not null comment ‘用户ID’,
role_id int(11) unsigned not null comment ‘角色ID’,
primary key (id),
key user_id (user_id),
key role_id (role_id),
constraint role_id foreign key (role_id) references r_roles(id) on
delete restrict ,
constraint user_id foreign key (user_id) references r_users(id) on
delete restrict
)

为了方便测试,先插入几条测试数据,r_users 的数据如图

R_roles的数据如图,插入三条数据,有三种角色,一是管理员角色,二是 root 权限,也就是超级管理员。三是 dba,数据管理员。这三种角色可以访问不同的 URL。

用户角色表中插入数据

为了生成上面 r_users 表中加密后的密码,攥写了使用 Bcrypt 加密的程序,代码如下:

import java.util.ArrayList;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public class BcryptTest {
public static void main(String[] args) {
ArrayList passwordArr = new ArrayList<>();
passwordArr.add(“123456”);
getUsersEncodePasswords(passwordArr);
}

private static void getUsersEncodePasswords(ArrayList passwordArr) {
for (String pass :passwordArr){
//密码加密
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String newPassword = passwordEncoder.encode(pass);
System.out.println(" 原始密码是:“+pass+”,加密密码为:"+newPassword);
//对比这两个密码是不是同一个密码
boolean match = passwordEncoder.matches(pass,newPassword);
System.out.println(“两个密码一致:”+match);
}
}
}

运行结果如图:

Bcrpt 加密算法非常安全,此算法自身实现了随机盐生成,很难被逆向破解。

创建一个新的项目,导入依赖,pom.xml代码如下:

<?xml version="1.0" encoding="UTF-8"?>


4.0.0

org.example
Security2
1.0-SNAPSHOT

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注网络安全获取)
img

还有兄弟不知道网络安全面试可以提前刷题吗?费时一周整理的160+网络安全面试题,金九银十,做网络安全面试里的显眼包!

王岚嵚工程师面试题(附答案),只能帮兄弟们到这儿了!如果你能答对70%,找一个安全工作,问题不大。

对于有1-3年工作经验,想要跳槽的朋友来说,也是很好的温习资料!

【完整版领取方式在文末!!】

93道网络安全面试题

内容实在太多,不一一截图了

黑客学习资源推荐

最后给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

1️⃣零基础入门
① 学习路线

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

image

② 路线对应学习视频

同时每个成长路线对应的板块都有配套的视频提供:

image-20231025112050764

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img

伙伴们一点帮助!

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

1️⃣零基础入门
① 学习路线

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

image

② 路线对应学习视频

同时每个成长路线对应的板块都有配套的视频提供:

image-20231025112050764

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-OqMx6v7M-1712548572010)]

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/445717
推荐阅读
相关标签
  

闽ICP备14008679号