create_time
datetime DEFAULT NULL,
update_time
datetime DEFAULT NULL,
status
tinyint(1) NOT NULL DEFAULT ‘1’,
PRIMARY KEY ( id
),
UNIQUE KEY unique_role_name
( role_name
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS t_role_permission
(
role_id
varchar(32) NOT NULL,
permission_id
varchar(32) NOT NULL,
PRIMARY KEY ( role_id
, permission_id
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS t_permission
(
id
varchar(32) NOT NULL,
code
varchar(32) NOT NULL COMMENT ‘权限标识’,
description
varchar(64) DEFAULT NULL COMMENT ‘描述’,
url
varchar(128) DEFAULT NULL COMMENT ‘请求地址’,
PRIMARY KEY ( id
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
- 基本配置
server:
port: 8080
spring:
thymeleaf:
cache: false
datasource:
url: jdbc:mysql://localhost:3306/spring_security?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
- 从以前的内存用户换为从数据库中读取用户
这里我们实现 UserDetailsService
接口,重写 loadUserByUsername(String username)
方法,基本逻辑:查询用户,及联表查询对应的权限。
@Component
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDto user = userMapper.getUserByUsername(username);
if (user != null) {
List permissions = userMapper.getPermissionsByUsername(username);
if (permissions != null) {
System.out.println(user.getUsername() + " has these permissions: " + permissions);
List authorities = new ArrayList();
permissions.stream().forEach(p -> authorities.add(new SimpleGrantedAuthority(p.getCode())));
// user.setAuthorities(Arrays.asList(new SimpleGrantedAuthority(“p1”))); // hard-coded permission
user.setAuthorities(authorities);
}
}
return user;
}
}
相关查询接口:
public interface PermissionMapper {
@Select(“SELECT * FROM t_permission”)
List getAllPermissions();
}
public interface UserMapper {
@Select(“SELECT * FROM t_user WHERE username = #{username}”)
UserDto getUserByUsername(@Param(“username”) String username);
/*
- SELECT p.* FROM t_permission p LEFT JOIN t_role_permission rp ON p.id = rp.permission_id
LEFT JOIN t_user_role ur ON rp.role_id = ur.role_id
LEFT JOIN t_user u ON ur.user_id = u.id
WHERE u.username = “test”;
- */
@Select(“SELECT p.* FROM t_permission p LEFT JOIN t_role_permission rp ON p.id = rp.permission_id LEFT JOIN t_user_role ur ON rp.role_id = ur.role_id LEFT JOIN t_user u ON ur.user_id = u.id WHERE u.username = #{username};”)
List getPermissionsByUsername(@Param(“username”) String username);
}
将用户数据源配置为从数据库中查询:
@Autowired
CustomUserDetailsService customUserDetailsService;
@Bean
public PasswordEncoder passwordEncoder () {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// Method1:
// There is no PasswordEncoder mapped for the id “null”
// PasswordEncoder encoder = new BCryptPasswordEncoder();
// String yourPassword = “123”;
// System.out.println("Encoded password: " + encoder.encode(yourPassword));
// auth.userDetailsService(customUserDetailsService).passwordEncoder(encoder);
auth.userDetailsService(customUserDetailsService);
}
- 从以前的硬编码的权限控制换为动态配置每个资源的权限
@Override
protected void configure(HttpSecurity http) throws Exception {
ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry authorizeRequests = http
.authorizeRequests();
List permissions = permissionMapper.getAllPermissions();
for (PermissionDto permission : permissions) {
authorizeRequests.antMatchers(permission.getUrl()).hasAuthority(permission.getCode());
}
authorizeRequests
.antMatchers(“/user/**”).authenticated()
.anyRequest().permitAll() // Let other request pass
.and()
.csrf().disable() // turn off csrf, or will be 403 forbidden
.formLogin() // Support form and HTTPBasic
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
最后
金三银四到了,送上一个小福利!
,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频**
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-rw5mf7iD-1711282601987)]
最后
金三银四到了,送上一个小福利!
[外链图片转存中…(img-KI4aV5tb-1711282601987)]
[外链图片转存中…(img-jDjyENxH-1711282601988)]
[外链图片转存中…(img-9PK55Juu-1711282601988)]