1,shiro對象(Relam)的建立步驟前端
工具類:目的是自定義(高級定製)受權和認證,spring
(1)ShiroFilterFactoryBean工廠:——》DefaultWebSecurityManager:-》建立 realm 對象,須要自定義類
這個類的目的是高級定製一個ShiroFilterFactoryBean工廠,生產自定義的Realm,
在這裏設置認證和受權
注意:shiro不單單要整合spring還要整合thymeleaf
@Configuration public class ShiroConfig { //ShiroFilterFactoryBean工廠:3 @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); //設置安全管理器 bean.setSecurityManager(defaultWebSecurityManager); //添加shiro內置過濾器 /* * anon:無需認證就能訪問 * authc:必須認證才能訪問 * user:必須擁有記住我功能才能使用 * perms:擁有對某個資源的權限才能訪問 * role:擁有某個角色權限才能訪問 * */ //攔截 Map<String, String> filterMap=new LinkedHashMap<>(); //這裏面的路徑是請求路徑 filterMap.put("/user/add","perms[user:add]"); filterMap.put("/user/update","authc"); bean.setFilterChainDefinitionMap(filterMap); //設置登陸請求 bean.setLoginUrl("/toLogin"); //設置未受權頁面 bean.setUnauthorizedUrl("/noauth"); return bean; } //DefaultWebSecurityManager:2 //@Qualifier做用,綁定指定的spring容器裏的bean @Bean public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //關聯userRealm securityManager.setRealm(userRealm); return securityManager; } //建立 realm 對象,須要自定義類 :1 @Bean(name = "userRealm")//被spring容器接管 public UserRealm userRealm(){ return new UserRealm(); } //整合ShiroDialect:用來整合shiro thymleaf @Bean public ShiroDialect getShiroDialect(){ return new ShiroDialect(); } }
(2)繼承抽象類AuthorizingRealm,裏面封裝的就是自定義的ShiroFilterFactoryBean工廠生產後的產物數據庫
在這個類自定義和重寫認證和受權安全
//自定義的 UserRealm public class UserRealm extends AuthorizingRealm { @Autowired UserService userService; //受權 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("執行了=>受權AuthorizationInfo"); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //info.addStringPermission("user:add");//受權寫死,便於實驗 //拿到當前登陸的這個對象 Subject subject = SecurityUtils.getSubject(); User currentUser =(User) subject.getPrincipal();//拿到user對象 //設置當前用戶的權限,數據從數據庫取 info.addStringPermission(currentUser.getPerms()); return info; } //認證 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("執行了=>認證AuthenticationInfo"); UsernamePasswordToken userToken= (UsernamePasswordToken) token; //從真實數據庫中拿數據 User user = userService.queryUserByName(userToken.getUsername()); if (user==null){ return null; } //密碼認證,shiro作 return new SimpleAuthenticationInfo(user,user.getPwd(),""); } }
到這裏shiro的認證和受權就結束了,最後就是結合controller層去去在前端體現了session
controller層小demoapp
@Controller public class MyController { //首頁 @RequestMapping({"/","/index"}) public String toIndex(Model model){ model.addAttribute("msg","Hello shiro"); return "index"; } @RequestMapping("user/add") public String add(){ return "user/add"; } @RequestMapping("user/update") public String update(){ return "user/update"; } @RequestMapping("toLogin") public String toLogin(){ return "login"; } @RequestMapping("login") public String login(String username,String password,String remember,Model model){ //獲取當前用戶 Subject subject= SecurityUtils.getSubject(); if (remember!=null){ subject.isRemembered(); } System.out.println(remember); //封裝用戶的登錄數據 UsernamePasswordToken token=new UsernamePasswordToken(username,password); try{ subject.login(token);//執行登陸方法,若是不報異常就success return "index"; }catch (UnknownAccountException e){//用戶名不存在 model.addAttribute("msg","用戶名錯誤"); return "login"; }catch (IncorrectCredentialsException e){//密碼不存在 model.addAttribute("msg","密碼錯誤"); return "login"; } } //沒有權限提示界面 @RequestMapping("/noauth") @ResponseBody public String unauthorized(){ return "未經受權沒法訪問此頁面"; } //註銷 @RequestMapping("logout") public String logout(){ //獲取當前用戶 Subject currentSubject= SecurityUtils.getSubject(); //註銷 currentSubject.logout(); return "redirect:/ "; } }
1,遊客界面ide
2,登陸界面 工具
3,不一樣角色訪問不一樣的功能頁面spa
3.1 用戶1(add權限)3d
3.12用戶2(update權限)
4,註銷(刪除subject至關於刪除session),返回遊客狀態
數據庫