当前位置:网站首页>srpingboot security demo
srpingboot security demo
2022-07-01 05:46:00 【Meta39】
pom.xml
<!--security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
基于配置文件yaml的认证(不建议)
spring:
#基于配置文件的认证(不建议)
security:
user:
name: test
password: test
基于配置类的认证(不建议)
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.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/** * 通过配置类实现认证(不建议) */
@Configuration
public class MyWebSecurity extends WebSecurityConfigurerAdapter {
//在方法中配置用户名和密码,作为用户登录的数据
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
auth.inMemoryAuthentication().withUser("lucy").password(bCryptPasswordEncoder.encode("123")).roles();
}
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
自定义认证类(建议)
注释MyWebSecurity
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.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import javax.annotation.Resource;
import javax.sql.DataSource;
/** * 自定义实现认证(建议) */
@Configuration
public class MyWebSecurity2 extends WebSecurityConfigurerAdapter {
@Resource
private UserDetailsService userDetailsService;
//注入数据源
@Resource
private DataSource dataSource;
@Bean
public PersistentTokenRepository persistentTokenRepository(){
JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
jdbcTokenRepository.setDataSource(dataSource);
// jdbcTokenRepository.setCreateTableOnStartup(true);
return jdbcTokenRepository;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
//登出
// http.logout().logoutUrl("/logout").logoutSuccessUrl("/login").permitAll();
//登录
http.formLogin()
// .loginPage("/login.html") //登录页面设置
// .loginProcessingUrl("/user/login")//登陆访问路径
// .defaultSuccessUrl("/hello").permitAll()//登录成功之后跳转的路径
.and()
.authorizeRequests()
.antMatchers("/", "/user/login").permitAll()//访问白名单
// 1. hasAuthority方法
// .antMatchers("/admin").hasAuthority("admin")//具有admin权限才能访问这个路径
// 2. hasAnyAuthority方法
// .antMatchers("/admin").hasAnyAuthority("admin,manager")
// 3. hasRole方法
// .antMatchers("/admin").hasRole("admin")//配置角色时要加ROLE_ 如ROLE_admin
// 4. hasAnyRole方法
.antMatchers("/admin").hasAnyRole("admin,test")
.anyRequest().authenticated()
//自动登录
.and()
.rememberMe().tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(60)//token过期时间秒
.userDetailsService(userDetailsService)
.and()
.csrf().disable();//关闭csrf跨站请求伪造攻击拦截
}
}
RedisConfig
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
/** * 防止数据存入redis乱码 */
@Bean(name="redisTemplate")
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
// 设置序列化
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);//已过期
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance , ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置redisTemplate
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
// key序列化
redisTemplate.setKeySerializer(stringSerializer);
// value序列化,可序列化对象
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// Hash key序列化
redisTemplate.setHashKeySerializer(stringSerializer);
// Hash value序列化,可序列化对象
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
Users实体类
import lombok.Data;
@Data
public class Users {
private Integer id;
private String username;
private String password;
}
UsersMapper
import com.fu.springsecuritydemo.entity.Users;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/** * 用redis模拟查询数据库 */
@Component
public class UsersMapper {
@Resource
private RedisTemplate redisTemplate;
public void insert(Users users){
redisTemplate.opsForValue().set(users.getId(),users);
}
public Users select(String username){
return (Users) redisTemplate.opsForValue().get(username);
}
public void delete(Integer userId){
redisTemplate.delete(userId);
}
}
MyUserDetailsService
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
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.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
@Resource
private UsersMapper usersMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//调用usersMapper根据用户名查询数据库
Users users = usersMapper.select(username);
//判断
if (users == null){
//数据库没有用户名,认证失败
throw new UsernameNotFoundException("用户名不存在!");
}
List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_admin");//admin是权限,ROLE_admin是角色
//从查询数据库返回users对象,得到用户名和密码,返回
return new User(users.getUsername(),new BCryptPasswordEncoder().encode(users.getPassword()),auths);
}
}
TestController
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class TestController {
@Resource
private RedisTemplate<String,Object> redisTemplate;
@GetMapping("hello")
public String hello(){
if (!redisTemplate.hasKey("lucy")){
Users users = new Users();
users.setId(1);
users.setUsername("lucy");
users.setPassword("123");
redisTemplate.opsForValue().set(users.getUsername(),users);
}
return "hello";
}
}
通过注解授权(建议)
启动类加上 @EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true) 注解
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class SpringSecurityDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringSecurityDemoApplication.class, args);
}
}
TestController
@GetMapping("hello2")
@Secured({
"ROLE_admin"})//需要多个角色才能访问则用英文逗号配置如ROLE_admin,ROLE_test
public String hello2(){
return "hello2";
}
边栏推荐
- excel初级应用案例——杜邦分析仪
- 云盘里资料被和谐了,怎么办?
- 轩逸保养手册
- SystemVerilog学习-09-进程间同步、通信和虚方法
- POL8901 LVDS转MIPI DSI 支持旋转图像处理芯片
- Looking for high school student developers with similar interests
- Oracle 序列+触发器
- Fragment upload and breakpoint resume
- 芯片,建立在沙粒上的帝国!
- Preliminary level of C language -- selected good questions on niuke.com
猜你喜欢

从诺奖知“边缘计算”的未来!

Diagramme dynamique Excel

Geoffrey Hinton:我的五十年深度学习生涯与研究心法

C language beginner level - realize the minesweeping game

π盘,让您电脑变成个人的私有云

穿越派·派盘 + 思源笔记 = 私人笔记本

This is the necessary software for college students 𞓜 knowledge management

穿越派 你的数据云行

Why use huluer pie disk instead of U disk?

He struggled day and night to protect his data
随机推荐
HCM 初学 ( 四 ) - 时间
Data governance: metadata management implementation (Part IV)
MySQL数据迁移遇到的一些错误
excel动态图表
Seven major technical updates that developers should pay most attention to on build 2022
Debug details under pycharm
Learn the customization and testing of fpga---ram IP from the bottom structure
rust猜数字游戏
【考研高数 自用】高数第一章基础阶段思维导图
ssm+mysql二手交易网站(论文+源码获取链接)
输入一个表达式(用字符串表示),求这个表达式的值。
Don't put your notes and videos everywhere!
从诺奖知“边缘计算”的未来!
FPGA - 7系列 FPGA内部结构之Clocking -01- 时钟架构概述
Wild melon or split melon?
不是你脑子不好用,而是因为你没有找到对的工具
How to add a gourd pie plate
Chapitre d'apprentissage mongodb: Introduction à la première leçon après l'installation
亲爱的派盘用户,我要向您表白!
健康照明中应用的LED照明灯