当前位置:网站首页>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";
}
边栏推荐
- Simple implementation of database connection pool
- 数据治理:数据治理框架(第一篇)
- Idea start view project port
- 分片上传与断点续传
- Mongodb學習篇:安裝後的入門第一課
- 激活函数简述
- SystemVerilog学习-08-随机约束和线程控制
- 2022.6.30-----leetcode. one thousand one hundred and seventy-five
- Diagramme dynamique Excel
- Learn the customization and testing of fpga---ram IP from the bottom structure
猜你喜欢

This is the necessary software for college students 𞓜 knowledge management

Speed regulation and stroke control based on Ti drv8424 driving stepper motor

SystemVerilog学习-10-验证量化和覆盖率

Crossing pie · pie pan + Mountain duck = local data management
SSM的教务管理系统(免费源码获取)

穿越派 你的数据云行

我从技术到产品经理的几点体会

教务管理系统(免费源码获取)

LeetCode 最大矩形,最大正方形系列 84. 85. 221. 1277. 1725. (单调栈,动态规划)

这才是大学生必备软件 | 知识管理
随机推荐
Xuanyi maintenance manual
穿越派 你的数据云行
Call us special providers of personal cloud services for College Students
Wild melon or split melon?
How to transmit and share 4GB large files remotely in real time?
Ssm+mysql second-hand trading website (thesis + source code access link)
CJC8988带2个立体声耳机驱动器的低功率立体声编解码器
C语言初阶——实现扫雷游戏
运行时候的导包搜索路径虽然pycharm中标红但不影响程序的执行
mysql 将毫秒数转为时间字符串
Preliminary level of C language -- selected good questions on niuke.com
Crossing sect · paipan + Siyuan notes = private notebook
SystemVerilog学习-10-验证量化和覆盖率
Common solutions for mobile terminals
数据治理:数据治理管理(第五篇)
Leetcode Max rectangle, Max square series 84 85. 221. 1277. 1725. (monotonic stack, dynamic programming)
Code shoe set - mt3149 · and - the data is not very strong. Violent pruning can deceive AC
HCM 初学 ( 四 ) - 时间
First defined here occurs during QT compilation. Causes and Solutions
ssm+mysql二手交易网站(论文+源码获取链接)