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工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以扫码领取!
![img](https://i-blog.csdnimg.cn/blog_migrate/11abea48a53810fa2518a5a8ce854c45.jpeg)
最后
我还为大家准备了一套体系化的架构师学习资料包以及BAT面试资料,供大家参考及学习
已经将知识体系整理好(源码,笔记,PPT,学习视频)
sdnimg.cn/images/e5c14a7895254671a72faed303032d36.jpg" alt=“img” style=“zoom: 33%;” />
最后
我还为大家准备了一套体系化的架构师学习资料包以及BAT面试资料,供大家参考及学习
已经将知识体系整理好(源码,笔记,PPT,学习视频)
[外链图片转存中…(img-4UYf05s2-1711357578433)]
[外链图片转存中…(img-iyCiDIeY-1711357578433)]
[外链图片转存中…(img-kCr1Ox8b-1711357578434)]
需要更多Java资料的小伙伴可以帮忙点赞+关注,点击传送门,即可免费领取!