SpringBoot+Mybatis+PostMan(七):用户角色权限访问控制入门(数据模拟实现,不带数据库)
Springboot+Mybatis+redis+postman项目实战总目录*
第二篇章:用户角色权限访问控制
SpringBoot+Mybatis+PostMan(八):用户角色权限访问控制一(数据库用户角色表查询组合)
SpringBoot+Mybatis+PostMan(九):用户角色权限访问控制二(加入资源表和资源角色对应表)
SpringBoot+Mybatis+PostMan(十):用户角色权限访问控制三(禁用session、启用token并集成redis)
继上一个项目Springboot+Mybatis+redis+postman项目实战总目录*实现用户session认证登陆后,我们紧接着对用户角色进行控制,用于实现不同觉得访问不同的接口,对于没有给到权限的角色实现禁止访问功能。在实现此功能前,我们先做一个热身项目,先不连接数据库,模拟一下数据库操作实现角色控制,这里我们主要实现employ角色和admin以不同角色实现不同页面访问,作为后面课程的入门。
项目源码下载地址:https://github.com/yeyuting-1314/JavaGoGoGo.git
项目目录如下:
先做一下准备工作。
一、准备工作
1. 新建一个spring boot项目,然后导入相应依赖。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
2. 实体类生成:
Admin类代码如下所示:
/** * @author yeyuting * @create 2021/1/21 */ public class Admin { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
Employee 类代码如下:
/** * @author yeyuting * @create 2021/1/21 */ public class Employee { private String id; private String username; private String password; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
二、正餐开始
1. 继承WebSecurityConfigurerAdapter
配置角色权限
/** * @author yeyuting * @create 2021/1/21 */ @Configuration @EnableWebSecurity //WebSecurityConfigurerAdapter 类是个适配器, 在配置的时候,需要我们自己写个配置类去继承他,然后编写自己所特殊需要的配置 public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override public void configure(WebSecurity web) throws Exception { super.configure(web); } @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService) .passwordEncoder(passwordEncoder());//passwoldEncoder是对密码的加密处理,如果user中密码没有加密,则可以不加此方法。注意加密请使用security自带的加密方式。 } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable()//禁用了 csrf 功能 .authorizeRequests()//限定签名成功的请求 .antMatchers("/decision/**","/govern/**","/employee/*").hasAnyRole("EMPLOYEE","ADMIN")//对decision和govern 下的接口 需要 USER 或者 ADMIN 权限 .antMatchers("/employee/login").permitAll()///employee/login 不限定 .antMatchers("/admin/**").hasRole("ADMIN")//对admin下的接口 需要ADMIN权限 .antMatchers("/oauth/**").permitAll()//不拦截 oauth 开放的资源 .anyRequest().permitAll()//其他没有限定的请求,允许访问 .and().anonymous()//对于没有配置权限的其他请求允许匿名访问 .and().formLogin()//使用 spring security 默认登录页面 .and().httpBasic();//启用http 基础验证 } }
2. 声明实现类,用于实现接住前端post传输过去的数据,并进行权限访问,从而给到相应对象相应的角色,从而访问到不同页面。
/** * @author yeyuting * @create 2021/1/21 */ @Service /* * 用户在登录时 Spring Security 会通过 UserDetailsService.loadUserByUsername() 方法获取登录的用户的详细信息, * 然后会将用户的数据封装进 UserDetails 对象中,因此这里需要实现UserDetailsService接口,并重写loadUserByUsername方法 * */ public class UserDetailServiceImpl implements UserDetailsService { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { //角色和权限共用GrantedAuthority接口,后面采集到的角色信息将存储到grantedAuthorities集合中 List<GrantedAuthority> grantedAuthorities = new ArrayList<>(); //生成环境是查询数据库获取username的角色用于后续权限判断(如:张三 admin) //这里暂时先不做数据库操作,给定假数据,我们后面再加入数据库 if (username.equals("employee")) { Employee employee = new Employee(); employee.setUsername("employee"); employee.setPassword("123456"); //对employ对象赋予ROLE_EMPLOYEE角色,存储到grantedAuthority中 GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_EMPLOYEE"); //将已经被赋予角色的grantedAuthority存储到grantedAuthorities集合中 grantedAuthorities.add(grantedAuthority); //创建一个用户,用于判断权限,请注意此用户名和方法参数中的username一致;BCryptPasswordEncoder是用来演示加密使用。 //这里主要是实现用户名和密码的核对,如果信息都正确才给开这个权限,这是一种安全策略 return new User(employee.getUsername(), new BCryptPasswordEncoder().encode(employee.getPassword()), grantedAuthorities); } if (username.equals("admin")) { Admin admin = new Admin(); admin.setUsername("admin"); admin.setPassword("123456"); GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_ADMIN"); grantedAuthorities.add(grantedAuthority); return new User(admin.getUsername(), new BCryptPasswordEncoder().encode(admin.getPassword()), grantedAuthorities); } else { return null; } } }
3.接下来实现业务层
AdminController类:
/** * @author yeyuting * @create 2021/1/21 */ @RestController @RequestMapping("/admin") public class AdminController { @GetMapping("/greeting") public String greeting() { return "Hello,World!"; } @GetMapping("/login") public String login() { return "login sucess"; } }
4. EmployeeController类:
/** * @author yeyuting * @create 2021/1/21 */ @RestController @RequestMapping("/employee") public class EmployeeController { @GetMapping("/greeting") public String greeting() { return "Hello,World!"; } @GetMapping("/login") public String login() { return "login sucess"; } }
三、正餐结束,接下里启动项目,前端post测试看看结果如何
1. 如果是employ角色访问自己的页面,访问成功
2. 如果是employ角色访问admin的页面,访问失败
3. 如果是admin角色访问admin的页面,访问成功
4. 如果是admin角色访问employee的页面,访问成功
这样一来,我们的角色控制入门就完成了,此项目灵感来源于文章https://www.jianshu.com/p/6a7dcef02bd5,十分的感谢,要不是这篇文章,我后面的数据库嵌入可能不会这么顺利的实现。
至此,结束。