1. Shiro框架簡介
Apache Shiro是一個強大且易用的Java安全框架,執行身份驗證、授權、密碼學和會話管理。使用Shiro的易於理解的API,您可以快速、輕松地獲得任何應用程序,從最小的移動應用程序到最大的網絡和企業應用程序。
1、 Authentication 認證 ---- 用戶登錄
2、 Authorization 授權 --- 用戶具有哪些權限
3、 Cryptography 安全數據加密
4、 Session Management 會話管理
5、 Web Integration web系統集成
6、 Interations 集成其它應用,spring、緩存框架
2.導入jar包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
3.創建ShiroConfig配置類
package org.jcut.config; import java.util.LinkedHashMap; import java.util.Map; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Shiro的配置類 * @author lenovo * */ @Configuration public class ShiroConfig { /** * 創建ShiroFilterFactoryBean */ @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); //設置安全管理器 shiroFilterFactoryBean.setSecurityManager(securityManager); //添加Shiro內置過濾器 /** * Shiro內置過濾器,可以實現權限相關的攔截器 * 常用的過濾器: * anon: 無需認證(登錄)可以訪問 * authc: 必須認證才可以訪問 * user: 如果使用rememberMe的功能可以直接訪問 * perms: 該資源必須得到資源權限才可以訪問 * role: 該資源必須得到角色權限才可以訪問 */ Map<String,String> filterMap = new LinkedHashMap<String,String>(); /*filterMap.put("/add", "authc"); filterMap.put("/update", "authc");*/ //放行login.html頁面 filterMap.put("/login", "anon"); filterMap.put("/index.html", "anon"); //放行靜態資源文件和不用攔截的訪問 filterMap.put("/js/**", "anon"); filterMap.put("/css/**", "anon"); filterMap.put("/big/**", "anon"); filterMap.put("/fonts/**", "anon"); filterMap.put("/images/**", "anon"); filterMap.put("/Products/**", "anon"); filterMap.put("/imgs/**", "anon"); filterMap.put("/comment/**", "anon"); filterMap.put("/Product_Detailed.html", "anon"); filterMap.put("/commodity/**", "anon"); filterMap.put("/pack/**", "anon"); filterMap.put("/type/**", "anon"); filterMap.put("/detail/**", "anon"); filterMap.put("/collect/selectBycId", "anon"); filterMap.put("/small/**", "anon"); filterMap.put("/user/select", "anon"); //授權過濾器 filterMap.put("/**", "authc"); //修改調整的登錄頁面 shiroFilterFactoryBean.setLoginUrl("/login.htm"); //設置未授權提示頁面 shiroFilterFactoryBean.setUnauthorizedUrl("/login.htm"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap); return shiroFilterFactoryBean; } /** * 創建DefaultWebSecurityManager */ @Bean(name="securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //關聯realm securityManager.setRealm(userRealm); return securityManager; } /** * 創建Realm */ @Bean(name="userRealm") public UserRealm getRealm(){ return new UserRealm(); } }
4.創建認證授權類
package org.jcut.config; import java.util.List; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.jcut.bean.User; import org.jcut.service.UserService; import org.springframework.beans.factory.annotation.Autowired; /** * 自定義Realm * @author lenovo * */ public class UserRealm extends AuthorizingRealm{ /** * 執行授權邏輯 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) { System.out.println("執行授權邏輯"); return null; } @Autowired private UserService userSerivce; /** * 執行認證邏輯 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException { System.out.println("執行認證邏輯"); ///編寫shiro判斷邏輯,判斷用戶名和密碼 //1.判斷用戶名 UsernamePasswordToken token = (UsernamePasswordToken)arg0; User user=new User(); user.setTel(token.getUsername()); user.setPwd(String.valueOf(token.getPassword())); List<User> list=userSerivce.select(user); if(list.size()==0){ //用戶名不存在 return null;//shiro底層會拋出UnKnowAccountException } //2.判斷密碼 return new SimpleAuthenticationInfo(list.get(0),token.getPassword(),token.getUsername()); } }
5.登錄Controller
@RequestMapping(value="/select",params = {"pwd","tel"}) public Object select(User user) { user.setPwd(MD5Util.encode2hex(user.getPwd())); /** * 使用Shiro編寫認證操作 */ //1.獲取Subject Subject subject = SecurityUtils.getSubject(); //2.封裝用戶數據 UsernamePasswordToken token = new UsernamePasswordToken(user.getTel(),user.getPwd()); try { subject.login(token); User user1=service.select(user).get(0); List list=new ArrayList<User>(); list.add(user1); redisTemplate.opsForValue().set(user1.getId(), list, 1l, TimeUnit.HOURS); data.setData(user1.getId()); data.setStatus("1"); data.setMsg("登陸成功!"); }catch(Exception e) { data.setData("0"); data.setStatus("0"); data.setMsg("登陸失敗!"); } return data; }