前言:
在日常应用的权限系统中,一个角色包含其他角色是一个很常见的需求。例如,在一个应用中如果有两个角色 admin和user,我们会希望所有user用户能做的事admin用户都可以做。为了实现这样的功能,我们可以把所有需要user用户访问的资源再赋一遍权限给admin用户,但是当我们的应用系统中有很多的角色时,这样的设计将变的极其复杂。所以srpng给我们提供了另一种实现方式,让我们很容易的可以把一种角色的权限赋给了另一角色。
环境:
spring-boot 版本:1.5.4.RELEASE
1.项目结构
[img]http://dl2.iteye.com/upload/attachment/0128/9140/8330ca7c-fc1a-389f-8b92-996f4042874d.png[/img]
2.配置类SecurityConfig.java
/**
*
*/
package falcon.chengf.security.samples.javaconfig.rolehierarchy;
import org.springframework.beans.factory.annotation.Autowired;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* @author: 作者: chengaofeng
* @date: 创建时间:2018-01-16 19:32:47
* @Description: TODO
* @version V1.0
*/
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void auth(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("password").authorities("ROLE_ADMIN").and()
.withUser("user").password("password").authorities("ROLE_USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().hasRole("USER")
.and()
.formLogin()
.permitAll();
}
}
在配置中我们定义了两种角色ROLE_ADMIN和ROLE_USER,分别赋予了两个用户admin和user,接着我们把/admin/目录下的资源限制为有ADMIN权限的用户才能访问,其他目录下的都需要USER权限。
3.权限继承关系配置类SecurityConfiguration.java
/**
*
*/
package falcon.chengf.security.samples.javaconfig.rolehierarchy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
/**
* @author: 作者: chengaofeng
* @date: 创建时间:2018-01-27 17:34:10
* @Description: TODO
* @version V1.0
*/
@Configuration
public class SecurityConfiguration {
@Bean
public RoleHierarchy roleHierarchy() {
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");
return roleHierarchy;
}
}
[b]ROLE_ADMIN > ROLE_USER[/b] 代表ADMIN角色包含USER角色
4.启动类SecurityRoleHierarchyApp.java
package falcon.chengf.security.samples.javaconfig.rolehierarchy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Hello world!
*
*/
@SpringBootApplication
public class SecurityRoleHierarchyApp
{
public static void main( String[] args )
{
SpringApplication.run(SecurityRoleHierarchyApp.class, args);
}
}
5.项目的pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>falcon.chengf</groupId>
<artifactId>security-samples-javaconfig-rolehierarchy</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>security-samples-javaconfig-rolehierarchy</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>${start-class}</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
6.admin页面 admin.html
<!DOCTYPE html>
<html>
<head>
<title>Static</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
hello, admin!
</body>
</html>
user页面 user.html
<!DOCTYPE html>
<html>
<head>
<title>Static</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
hello user!
</body>
</html>
7.启动项目
选中启动类,选择 Run As->Java application,启动后在浏览器中输入
http://localhost:8080/admin/admin.html
之后我们会被重定向到login页面
[img]http://dl2.iteye.com/upload/attachment/0128/9142/16ba9ed8-c71a-33cc-a2a0-cbd1e588287d.png[/img]
输入用户名:admin 和密码:password,我们就会看到admin页面
[img]http://dl2.iteye.com/upload/attachment/0128/9144/724b586c-a104-3203-a2b1-e3ad2b76257b.png[/img]
之后我们再在浏览器中输入http://localhost:8080/user/user.html,也能正常访问
[img]http://dl2.iteye.com/upload/attachment/0128/9146/66a89e3e-f97e-37f8-9589-e56d5b1ba0d8.png[/img]
我们清除器记录,再重新访问http://localhost:8080/user/user.html,之后再次重定向到login页面,输入用户名:user和密码:password,就会看到user页面,但是再在浏览器中输入http://localhost:8080/admin/admin.html,会出现403页面
[img]http://dl2.iteye.com/upload/attachment/0128/9150/c2240088-203a-31a9-8966-86d8a22beda1.png[/img]
[url=https://github.com/fengyilin/spring-security-sample/tree/master]下载源码[/url]