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,十分的感謝,要不是這篇文章,我后面的數據庫嵌入可能不會這么順利的實現。
至此,結束。