下面是Spring Security实现基于RBAC的权限表达式动态访问控制的操作方法的完整攻略:
步骤一:初始化Spring Security
使用Spring Security提供的依赖,在pom.xml文件中配置以下依赖项:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
完成后,需要在Spring应用程序的配置文件中启用Spring Security:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasRole("USER")
.and()
.formLogin();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/resources/**");
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("{noop}admin").roles("ADMIN")
.and()
.withUser("user").password("{noop}user").roles("USER");
}
}
步骤二:配置基于RBAC的权限表达式
在Spring Security中使基于RBAC的权限表达式成为真正动态的,可以使用Spring EL,这样就可以对当前用户的角色进行动态处理。
首先,需要定义一个角色和对应的权限,可以将这些数据存储到数据库中:
CREATE TABLE Role (
id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
name TEXT NOT NULL,
description TEXT DEFAULT NULL
);
CREATE TABLE Permission (
id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
name TEXT NOT NULL,
description TEXT DEFAULT NULL
);
CREATE TABLE Role_Permission (
role_id INTEGER NOT NULL,
permission_id INTEGER NOT NULL,
PRIMARY KEY (role_id, permission_id),
CONSTRAINT ROLE_PERM_ROLE_FK FOREIGN KEY (role_id)
REFERENCES Role (id),
CONSTRAINT ROLE_PERM_PERM_FK FOREIGN KEY (permission_id)
REFERENCES Permission (id)
);
INSERT INTO Role (name, description) VALUES ('admin', '管理者');
INSERT INTO Role (name, description) VALUES ('user', '普通用户');
INSERT INTO Permission (name, description) VALUES ('create', '创建');
INSERT INTO Permission (name, description) VALUES ('read', '读取');
INSERT INTO Permission (name, description) VALUES ('update', '更新');
INSERT INTO Permission (name, description) VALUES ('delete', '删除');
INSERT INTO Role_Permission (role_id, permission_id) VALUES (1, 1);
INSERT INTO Role_Permission (role_id, permission_id) VALUES (1, 2);
INSERT INTO Role_Permission (role_id, permission_id) VALUES (1, 3);
INSERT INTO Role_Permission (role_id, permission_id) VALUES (1, 4);
INSERT INTO Role_Permission (role_id, permission_id) VALUES (2, 2);
接下来,需要在Spring Security的配置文件中添加以下代码来读取数据库中的角色和权限信息:
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AppConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Bean
public RoleHierarchyImpl roleHierarchy() {
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
roleHierarchy.setHierarchy("ROLE_admin > ROLE_user");
return roleHierarchy;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/*").access("hasRole('admin') or hasRole('user')")
.antMatchers("/admin/**").access("hasRole('admin')").and().formLogin();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
JdbcUserDetailsManager userDetailsService = new JdbcUserDetailsManager();
userDetailsService.setDataSource(dataSource);
userDetailsService.setSqlUsersByUsernameQuery(
"select username,password,enabled from users where username=?");
userDetailsService.setSqlRolesByUsernameQuery(
"select u.username, r.name from users u, user_roles ur, role r where u.id = ur.user_id and ur.role_id = r.id and u.username=?");
auth.userDetailsService(userDetailsService);
}
}
步骤三:添加角色和权限
在定义了角色和权限之后,需要为用户分配角色和权限:
ALTER TABLE users
ADD COLUMN enabled BOOLEAN DEFAULT TRUE NOT NULL;
CREATE TABLE user_roles (
user_id INTEGER NOT NULL,
role_id INTEGER NOT NULL,
PRIMARY KEY (user_id, role_id),
CONSTRAINT users_roles_users_FK FOREIGN KEY (user_id)
REFERENCES users (id),
CONSTRAINT users_roles_roles_FK FOREIGN KEY (role_id)
REFERENCES Role (id)
);
INSERT INTO users VALUES (DEFAULT, 'admin', 'admin@example.com', 'password', TRUE);
INSERT INTO users VALUES (DEFAULT, 'user', 'user@example.com', 'password', TRUE);
INSERT INTO user_roles VALUES (1, 1);
INSERT INTO user_roles VALUES (2, 2);
示例一:使用Spring EL动态控制页面访问权限
首先,创建一个基本的Spring MVC控制器:
@Controller
public class HomeController {
@GetMapping("/")
@PreAuthorize("hasRole('USER')")
public String index(Model model) {
return "index";
}
@GetMapping("/admin")
@PreAuthorize("hasRole('ADMIN')")
public String admin(Model model) {
return "admin";
}
}
在访问/index时,只有拥有USER角色的用户可以查看,而在访问/admin时,只有拥有ADMIN角色的用户才能查看。
示例二:使用代码动态控制页面访问权限
在使用代码动态控制页面访问权限时,可以在Spring Security的配置文件中添加以下代码:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/user/**").access("hasRole('USER') or hasRole('ADMIN')")
.antMatchers("/admin/**").access("hasRole('ADMIN')")
.and()
.formLogin();
}
}
在访问/user/时,只有拥有USER或者ADMIN角色的用户可以查看,而在访问/admin/时,只有拥有ADMIN角色的用户才能查看。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security实现基于RBAC的权限表达式动态访问控制的操作方法 - Python技术站