Apache Shiro是一個強大且易用的Java安全框架,執行身份驗證、受權、密碼和會話管理。java
三個核心組件:Subject, SecurityManager 和 Realms.spring
<!--整合Shiro安全框架--><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.4.0</version></dependency><!--集成jwt實現token認證--><dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.2.0</version></dependency>
@Configurationpublic class ShiroConfig {/** * ShiroFilterFactoryBean */@Beanpublic ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) { ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();//設置安全管理器 factoryBean.setSecurityManager(defaultWebSecurityManager);// 添加shiro的內置過濾器/* * anon:無需認證就能夠訪問 * authc:必須認證才能訪問 * user:必須擁有 記住我 功能才能用 * perms:擁有對某個資源的權限能訪問 * role:擁有某個角色權限能訪問 */Map<String, String> filterMap = new LinkedHashMap<>();// 放行不須要權限認證的接口//放行登陸接口filterMap.put("/login/**", "anon");//放行用戶接口filterMap.put("/", "anon"); // 網站首頁 //認證管理員接口filterMap.put("/administrators/**", "authc"); factoryBean.setFilterChainDefinitionMap(filterMap);// 設置無權限時跳轉的 url// 設置登陸的請求factoryBean.setLoginUrl("/login/toLogin");return factoryBean; }/** * 注入 DefaultWebSecurityManager */@Bean(name = "securityManager")public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("customRealm") CustomRealm customRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();//關聯CustomRealm securityManager.setRealm(customRealm);return securityManager; }/** * 注入 securityManager */@Beanpublic CustomRealm customRealm() {return new CustomRealm(); } }
@Componentpublic class CustomRealm extends AuthorizingRealm { @Autowired AdministratorsService administratorsService;/* * 設置加密方式 */{ HashedCredentialsMatcher mather = new HashedCredentialsMatcher();// 加密方式mather.setHashAlgorithmName("md5");// 密碼進行一次運算mather.setHashIterations(512);this.setCredentialsMatcher(mather); }/** * 受權 */@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("————受權————doGetAuthorizationInfo————");return null; }/** * 認證 */@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("————認證————doGetAuthenticationInfo————"); UsernamePasswordToken userToken = (UsernamePasswordToken) token;// 鏈接數據庫 查詢用戶數據QueryWrapper<Administrators> wrapper = new QueryWrapper<>(); wrapper.eq("username", userToken.getUsername()); Administrators administrators = administratorsService.getOne(wrapper);if (administrators == null) {return null; // 拋出異常 UnknownAccountException }// 密碼認證,shiro作return new SimpleAuthenticationInfo("", administrators.getPassword(), ""); } }
//用戶名登陸@ApiOperation(value = "管理員登陸", notes = "用戶名登陸--不進行攔截") @PostMapping("/doLogin")public String doLogin(@RequestParam("username") String username, @RequestParam("password") String password, HttpSession session,Model model) {// 獲取當前的用戶Subject subject = SecurityUtils.getSubject();// 封裝用戶的登陸數據UsernamePasswordToken token = new UsernamePasswordToken(username, password);try { subject.login(token);//保存session會話 管理員名字session.setAttribute("adname", username);return "admin"; } catch (UnknownAccountException e) { model.addAttribute("usererror", "用戶名錯誤!請從新輸入。");return "login"; } catch (IncorrectCredentialsException ice) { model.addAttribute("pwerror", "密碼錯誤!請從新輸入。");return "login"; } }