先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上网络安全知识点,真正体系化!
需要体系化学习资料的朋友,可以加我V获取:vip204888 (备注网络安全)
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
public class UserController {
@RequestMapping(“/user/hello”)
public String hello() {
return “user,Hello !”;
}
}
AdminController类
package com.example.demo3springsecurity.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AdminController {
@RequestMapping(“/admin/hello”)
public String hello() {
return “admin,Hello !”;
}
}
2. 配置两个角色
本来用户和角色是保存在数据库中的,这里只是单纯地创建了两个存放于内存的用户和角色
创建config目录,并创建SecurityConfig类
package com.example.demo3springsecurity.config;
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 SecurityConfig extends WebSecurityConfigurerAdapter {
/*不对密码进行加密*/
@Bean
PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
/*管理员用户 具备ADMIN和USER角色*/
.withUser(“admin”).password(“admin”).roles(“ADMIN”, “USER”)
.and()
/*普通用户*/
.withUser(“aoxiu”).password(“aoxiu”).roles(“USER”);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
/*普通用户访问的url*/
.antMatchers(“/user/**”).hasRole(“USER”)
/*管理员用户访问的url*/
.antMatchers(“/admin/**”).hasRole(“ADMIN”)
.anyRequest().authenticated() //其他多有路径都必须认证
.and()
.formLogin()
.loginProcessingUrl(“/login”)
.permitAll() //访问“/login”接口不需要进行身份认证了,防止重定向死循环
.and()
.csrf().disable(); //关闭csrf
}
}
然后就可以发现,若要访问admin/hello,用户名和密码必须是admin才可以
若使用aoxiu这种用户的身份就会报错
### 三、基于数据库的认证
#### 1、SpringSecurity基于数据库认证
1. 创建项目,添加如下依赖
![在这里插入图片描述](https://img-blog.csdnimg.cn/7ec50386b596485b949e2fe9de929df0.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5aWl5aaZ5peg56m5,size_12,color_FFFFFF,t_70,g_se,x_16)
lombok用于使用注解替代getter、setter等方法
![在这里插入图片描述](https://img-blog.csdnimg.cn/547e093d08cf4cb7a92173434b6cbafd.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5aWl5aaZ5peg56m5,size_14,color_FFFFFF,t_70,g_se,x_16)
2. 在application.yml文件中配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
logging:
level:
com.example.bdatabaserole.mapper: debug #打印SQL语句
mybatis:
mapper-locations: classpath:mappers/*.xml
type-aliases-package: com.example.securitydatebase.mapper
server:
port: 8082
3. 创建实体类
UserInfo
package com.beixi.entity;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Data //lombok注解省略get/set等方法
public class UserInfo implements Serializable,UserDetails {
private int id;
private String username;
private String password;
private List<Role> roleList;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> authorities = new ArrayList<>();
for (Role role : roleList) {
//数据库role表字段中是以ROLE\_开头的,所以此处不必再加ROLE\_
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
return authorities;
}
/\*\*
* 指示用户的账户是否已过期。无法验证过期的账户。
* 如果用户的账户有效(即未过期),则返回true,如果不在有效就返回false
*/
@Override
public boolean isAccountNonExpired() {
return true;
}
/\*\*
* 指示用户是锁定还是解锁。无法对锁定的用户进行身份验证。
* 如果用户未被锁定,则返回true,否则返回false
*/
@Override
public boolean isAccountNonLocked() {
return true;
}
/\*\*
* 指示用户的凭证(密码)是否已过期。过期的凭证阻止身份验证
* 如果用户的凭证有效(即未过期),则返回true
* 如果不在有效(即过期),则返回false
*/
@Override
public boolean isCredentialsNonExpired() {
return true;
}
/\*\*
* 指示用户是启用还是禁用。无法对禁用的用户进行身份验证
* 如果启用了用户,则返回true,否则返回false
*/
@Override
public boolean isEnabled() {
return true;
}
}
4. 创建Mapper接口和Service层
UserMapper
package com.example.securitydatebase.mapper;
import com.example.securitydatebase.entity.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface UserMapper {
@Select(“select * from user where username = #{username}”)
UserInfo getUserByUsername(String username);
}
UserInfoService
package com.example.securitydatebase.service;
import com.example.securitydatebase.entity.UserInfo;
import com.example.securitydatebase.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserInfoService {
@Autowired
private UserMapper userMapper;
public UserInfo getUserInfo(String username){
return userMapper.getUserByUsername(username);
}
}
5. 创建Controller层
package com.example.securitydatebase.controller;
import com.example.securitydatebase.entity.UserInfo;
import com.example.securitydatebase.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
public class UserController {
@Autowired
private UserInfoService userInfoService;
@GetMapping("/getUser")
public UserInfo getUser(@RequestParam String username){
return userInfoService.getUserInfo(username);
}
}
6. 身份认证
CustomUserDetailsService
package com.example.securitydatebase.service;
import com.example.securitydatebase.entity.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserInfoService userInfoService;
/\*\*
* 需新建配置类注册一个指定的加密方式Bean,或在下一步Security配置类中注册指定
*/
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 通过用户名从数据库获取用户信息
UserInfo userInfo = userInfoService.getUserInfo(username);
if (userInfo == null) {
throw new UsernameNotFoundException("用户不存在");
}
//得到用户角色
String role=userInfo.getRole();
//角色集合
List<GrantedAuthority> authorities=new ArrayList<>();
//角色必须以“ROLE\_”开头,如果数据中没有,则在这里添加
authorities.add(new SimpleGrantedAuthority("ROLE\_"+role));
return new User(
userInfo.getUsername(),
//因为数据库是明文,所以这里需要加密密码
passwordEncoder.encode(userInfo.getPassword()),
authorities
);
}
}
7. SpringSecurity配置
WebSecurityConfig
package com.example.securitydatebase.config;
import com.example.securitydatebase.service.CustomUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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 //是Spring Security用于启用Web安全的注解
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Lazy
private CustomUserDetailsService userDatailService;
/\*\*
* 指定加密方式
*/
@Bean
public PasswordEncoder passwordEncoder(){
// 使用BCrypt加密密码
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
// 从数据库读取的用户进行身份认证
.userDetailsService(userDatailService)
.passwordEncoder(passwordEncoder());
}
}
8. 建立test数据库,建立user表
![在这里插入图片描述](https://img-blog.csdnimg.cn/72fbd98785d24189af639ba7b5ff4955.png)
9. 测试
![在这里插入图片描述](https://img-blog.csdnimg.cn/4e1aab3421ab4c049ef205bd53984c5e.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5aWl5aaZ5peg56m5,size_20,color_FFFFFF,t_70,g_se,x_16)
注意这一段只是用于认证,但是还没有限制角色的访问
#### 2、角色访问控制
1. 开启访问权限,在WebSecurityConfig中添加@EnableGlobalMethodSecurity
![在这里插入图片描述](https://img-blog.csdnimg.cn/08c66b3797554aa1ae1e2513e47f7587.png)
prePostEnabled=true会解锁@PreAuthorize和@PostAuthorize两个注解,@preAuthorize注解会在方法执行前进行验证,而@PostAuthorize注解在方法执行后进行验证
是不是有点懵,没关系,看后面就懂了
2. 在控制层添加访问接口
UserController类增加方法的访问权限
@PreAuthorize("hasAnyRole('user')") // 只能user角色才能访问该方法
@GetMapping("/user")
public String user(){
return "hello,user";
}
@PreAuthorize("hasAnyRole('admin')") // 只能admin角色才能访问该方法
@GetMapping("/admin")
public String admin(){
return "hello,admin";
}
PreAuthorize在执行前会首先验证是否user角色
3. 测试
使用user登录时无法访问/admin,
使用admin界面时,无法访问/user
#### 3、密码加密保护
1. 修改Mapper接口
package com.example.securitydatebase.mapper;
import com.example.securitydatebase.entity.UserInfo;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface UserMapper {
@Select(“select * from user where username = #{username}”)
UserInfo getUserByUsername(String username);
// 添加用户
@Insert("insert into user(username, password) value(#{username}, #{password})")
int insertUserInfo(UserInfo userInfo);
}
2. 修改service类
package com.example.securitydatebase.service;
import com.example.securitydatebase.entity.UserInfo;
import com.example.securitydatebase.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@Service
public class UserInfoService {
@Autowired
private UserMapper userMapper;
@Autowired
private PasswordEncoder passwordEncoder;
public int insertUser(UserInfo userInfo){
// 加密密码
userInfo.setPassword(passwordEncoder.encode(userInfo.getPassword()));
return userMapper.insertUserInfo(userInfo);
}
public UserInfo getUserInfo(String username){
return userMapper.getUserByUsername(username);
}
}
3. 修改controller
### 给大家的福利
**零基础入门**
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
![](https://img-blog.csdnimg.cn/img_convert/95608e9062782d28f4f04f821405d99a.png)
同时每个成长路线对应的板块都有配套的视频提供:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a91b9e8100834e9291cfcf1695d8cd42.png#pic_center)
因篇幅有限,仅展示部分资料
**需要体系化学习资料的朋友,可以加我V获取:vip204888 (备注网络安全)**
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化资料的朋友,可以点击这里获取](https://bbs.csdn.net/topics/618540462)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
个大的方向学习准没问题。
![](https://img-blog.csdnimg.cn/img_convert/95608e9062782d28f4f04f821405d99a.png)
同时每个成长路线对应的板块都有配套的视频提供:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a91b9e8100834e9291cfcf1695d8cd42.png#pic_center)
因篇幅有限,仅展示部分资料
**需要体系化学习资料的朋友,可以加我V获取:vip204888 (备注网络安全)**
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化资料的朋友,可以点击这里获取](https://bbs.csdn.net/topics/618540462)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**