javascript
java shiro security_安全框架Shiro和SpringSecurity的比较
兩個基本的概念
安全實體:系統(tǒng)需要保護的具體對象數(shù)據(jù)
權(quán)限:系統(tǒng)相關(guān)的功能操作,例如基本的CRUD
Shiro
首先Shiro較之 Spring Security,Shiro在保持強大功能的同時,還在簡單性和靈活性方面擁有巨大優(yōu)勢。
Shiro是一個強大而靈活的開源安全框架,能夠非常清晰的處理認證、授權(quán)、管理會話以及密碼加密。如下是它所具有的特點:
易于理解的 Java Security API;
簡單的身份認證(登錄),支持多種數(shù)據(jù)源(LDAP,JDBC,Kerberos,ActiveDirectory 等);
對角色的簡單的簽權(quán)(訪問控制),支持細粒度的簽權(quán);
支持一級緩存,以提升應(yīng)用程序的性能;
內(nèi)置的基于 POJO 企業(yè)會話管理,適用于 Web 以及非 Web 的環(huán)境;
異構(gòu)客戶端會話訪問;
非常簡單的加密 API;
不跟任何的框架或者容器捆綁,可以獨立運行。
Shiro四大核心功能:Authentication,Authorization,Cryptography,Session Management
Shiro架構(gòu)
Shiro三個核心組件:Subject, SecurityManager 和 Realms.
Subject:主體,可以看到主體可以是任何可以與應(yīng)用交互的 “用戶”;
SecurityManager:相當(dāng)于 SpringMVC 中的 DispatcherServlet 或者 Struts2 中的 FilterDispatcher;是 Shiro 的心臟;所有具體的交互都通過 SecurityManager 進行控制;它管理著所有 Subject、且負責(zé)進行認證和授權(quán)、及會話、緩存的管理。
Realm:域,Shiro從從Realm獲取安全數(shù)據(jù)(如用戶、角色、權(quán)限),就是說SecurityManager要驗證用戶身份,那么它需要從Realm獲取相應(yīng)的用戶進行比較以確定用戶身份是否合法;也需要從Realm得到用戶相應(yīng)的角色/權(quán)限進行驗證用戶是否能進行操作;可以把Realm看成DataSource,即安全數(shù)據(jù)源。
兩個配置類ShiroConfig和UserRealm
1 packagecom.example.shirodemo.config;2
3 importat.pollux.thymeleaf.shiro.dialect.ShiroDialect;4 importorg.apache.shiro.spring.web.ShiroFilterFactoryBean;5 importorg.apache.shiro.web.mgt.DefaultWebSecurityManager;6 importorg.springframework.beans.factory.annotation.Qualifier;7 importorg.springframework.context.annotation.Bean;8 importorg.springframework.context.annotation.Configuration;9
10 importjava.util.LinkedHashMap;11 importjava.util.Map;12
13 /**
14 * shiro配置類15 */
16 @Configuration17 public classShiroConfig {18 /**
19 * 創(chuàng)建ShiroFilterFactoryBean20 */
21 @Bean22 public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){23 ShiroFilterFactoryBean shiroFilterFactoryBean=newShiroFilterFactoryBean();24 //設(shè)置安全管理器
25 shiroFilterFactoryBean.setSecurityManager(securityManager);26 //添加Shiro攔截器
27 /**
28 * Shiro 內(nèi)置過濾器,可以實現(xiàn)權(quán)限相關(guān)的攔截器29 * anon:無需認證(登錄)可以直接訪問30 * authc:必須認證才能訪問31 * user:如果使用rememberMe的功能才可以訪問32 * perms:該資源得到資源權(quán)限才可以訪問33 * role:該資源必須得到角色權(quán)限才可以訪問34 */
35 Map filterMap=new LinkedHashMap<>();36 /*filterMap.put("/add","authc");37 filterMap.put("/update","authc");*/
38 //filterMap.put("/test","anon");
39 filterMap.put("/login","anon");40 //添加Shiro授權(quán)攔截器
41 filterMap.put("/add","perms[添加]");42 filterMap.put("/foresee","perms[預(yù)言未來]");43 filterMap.put("/update","perms[修改]");44 filterMap.put("/delete","perms[刪除]");45 //filterMap.put("/update","perms[]");46 //filterMap.put("/delete","perms[]");47 //filterMap.put("/getAll","perms[]");
48 filterMap.put("/*","authc");49 //跳轉(zhuǎn)到登陸的頁面
50 shiroFilterFactoryBean.setLoginUrl("/tologin");51 //設(shè)置未授權(quán)的頁面
52 shiroFilterFactoryBean.setUnauthorizedUrl("/unAuth");53 shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);54
55 returnshiroFilterFactoryBean;56 }57 /**
58 * 創(chuàng)建DefaultWebSecurityManager59 */
60 @Bean("securityManager")61 public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){62 DefaultWebSecurityManager securityManager=newDefaultWebSecurityManager();63 //關(guān)聯(lián)Realm
64 securityManager.setRealm(userRealm);65 returnsecurityManager;66 }67 /**
68 * 創(chuàng)建Realm69 */
70 @Bean("userRealm")71 publicUserRealm getRealm(){72 UserRealm userRealm=newUserRealm();73 returnuserRealm;74 }75 /**
76 * 配置shiroDialect,用于thymeleaf和shiro標(biāo)簽配合使用77 */
78 @Bean79 publicShiroDialect getShiroDialect(){80 ShiroDialect shiroDialect=newShiroDialect();81 returnshiroDialect;82 }83 }
packagecom.example.shirodemo.config;importcom.example.shirodemo.bean.Permission;importcom.example.shirodemo.bean.User;importcom.example.shirodemo.service.IPermissionService;importcom.example.shirodemo.service.IUserService;importorg.apache.shiro.SecurityUtils;import org.apache.shiro.authc.*;importorg.apache.shiro.authz.AuthorizationInfo;importorg.apache.shiro.authz.SimpleAuthorizationInfo;importorg.apache.shiro.realm.AuthorizingRealm;importorg.apache.shiro.subject.PrincipalCollection;importorg.apache.shiro.subject.Subject;importorg.springframework.security.core.GrantedAuthority;importorg.springframework.security.core.authority.SimpleGrantedAuthority;importjavax.annotation.Resource;importjava.util.ArrayList;importjava.util.List;/*** 自定義Realm*/
public class UserRealm extendsAuthorizingRealm {
@ResourceprivateIUserService userService;
@ResourceprivateIPermissionService permissionService;/*** 執(zhí)行授權(quán)邏輯
*@paramprincipalCollection
*@return
*/@OverrideprotectedAuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("執(zhí)行授權(quán)邏輯");/*** 給資源授權(quán)*/SimpleAuthorizationInfo simpleAuthorizationInfo=newSimpleAuthorizationInfo();//添加授權(quán)字符串//simpleAuthorizationInfo.addStringPermission("user:add");//--------------------認證賬號
Subject subject=SecurityUtils.getSubject();
User user=(User)subject.getPrincipal();
User user1=userService.findById(user.getId());if(user1==null){//用戶名不存在
return null;
}//-------------------開始授權(quán)
List permissions =permissionService.getPermissionByUserId(user1.getId());for(Permission per : permissions) {
simpleAuthorizationInfo.addStringPermission(per.getName());
System.out.println("擁有權(quán)限:"+per.getName());
}returnsimpleAuthorizationInfo;
}/*** 執(zhí)行認證邏輯
*@paramauthenticationToken
*@return*@throwsAuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throwsAuthenticationException {
System.out.println("執(zhí)行認證邏輯");/*** 判斷ShiroRealm邏輯UsernamePasswordToken是否正確*/
//1判斷用戶名
UsernamePasswordToken usernamePasswordToken=(UsernamePasswordToken)authenticationToken;
User user=userService.findByname(usernamePasswordToken.getUsername());if(user==null){//用戶名不存在
return null;
}//判斷密碼是否正確
return new SimpleAuthenticationInfo(user,user.getPassword(),"");
}
}
認證過程
1 /**
2 * 登錄邏輯處理3 */
4 @RequestMapping("/login")5 publicString login(User user, Model model) {6 /**
7 *使用shiro編寫認證操作8 */
9 //1:獲取subject
10 Subject subject =SecurityUtils.getSubject();11 //2:封裝用戶賬號和密碼
12 UsernamePasswordToken usernamePasswordToken = newUsernamePasswordToken(user.getUsername(), user.getPassword());13 //3:執(zhí)行登錄方法
14 try{15 subject.login(usernamePasswordToken);16 model.addAttribute(user);17 //登錄成功18 //成功后跳轉(zhuǎn)到19 //return "redirect:/test";
20 return "/test";21 } catch(UnknownAccountException e) {22 //e.printStackTrace();23 //登錄失敗用戶名不存在
24 model.addAttribute("msg","用戶名不存在");25 return "login";26 }catch(IncorrectCredentialsException e){27 //登錄失敗密碼錯誤
28 model.addAttribute("msg","密碼錯誤");29 return "login";30 }31 }32 }
Subject拿到用戶數(shù)據(jù)后走UserRealm 類里面的認證邏輯,授權(quán)過程比較簡單可以看你上面的代碼,
Shiro配置攔截器
//添加Shiro攔截器
27???????? /**
28 * Shiro 內(nèi)置過濾器,可以實現(xiàn)權(quán)限相關(guān)的攔截器
29 *???? anon:無需認證(登錄)可以直接訪問
30 *???? authc:必須認證才能訪問
31 *???? user:如果使用rememberMe的功能才可以訪問
32 *???? perms:該資源得到資源權(quán)限才可以訪問
33 *???? role:該資源必須得到角色權(quán)限才可以訪問
34????????? */
Spring Security
除了不能脫離Spring,shiro的功能它都有。而且Spring Security對Oauth、OpenID也有支持,Shiro則需要自己手動實現(xiàn)。Spring Security的權(quán)限細粒度更高,畢竟Spring Security是Spring家族的。
Spring Security一般流程為:
①當(dāng)用戶登錄時,前端將用戶輸入的用戶名、密碼信息傳輸?shù)胶笈_,后臺用一個類對象將其封裝起來,通常使用的是UsernamePasswordAuthenticationToken這個類。
②程序負責(zé)驗證這個類對象。驗證方法是調(diào)用Service根據(jù)username從數(shù)據(jù)庫中取用戶信息到實體類的實例中,比較兩者的密碼,如果密碼正確就成功登陸,同時把包含著用戶的用戶名、密碼、所具有的權(quán)限等信息的類對象放到SecurityContextHolder(安全上下文容器,類似Session)中去。
③用戶訪問一個資源的時候,首先判斷是否是受限資源。如果是的話還要判斷當(dāng)前是否未登錄,沒有的話就跳到登錄頁面。
④如果用戶已經(jīng)登錄,訪問一個受限資源的時候,程序要根據(jù)url去數(shù)據(jù)庫中取出該資源所對應(yīng)的所有可以訪問的角色,然后拿著當(dāng)前用戶的所有角色一一對比,判斷用戶是否可以訪問。
注:
OAuth在"客戶端"與"服務(wù)提供商"之間,設(shè)置了一個授權(quán)層(authorization layer)。"客戶端"不能直接登錄"服務(wù)提供商",只能登錄授權(quán)層,以此將用戶與客戶端區(qū)分開來。"客戶端"登錄授權(quán)層所用的令牌(token),與用戶的密碼不同。用戶可以在登錄的時候,指定授權(quán)層令牌的權(quán)限范圍和有效期。
"客戶端"登錄授權(quán)層以后,"服務(wù)提供商"根據(jù)令牌的權(quán)限范圍和有效期,向"客戶端"開放用戶儲存的資料。
OpenID 系統(tǒng)的第一部分是身份驗證,即如何通過 URI 來認證用戶身份。目前的網(wǎng)站都是依靠用戶名和密碼來登錄認證,這就意味著大家在每個網(wǎng)站都需要注冊用戶名和密碼,即便你使用的是同樣的密碼。如果使用 OpenID ,你的網(wǎng)站地址(URI)就是你的用戶名,而你的密碼安全的存儲在一個 OpenID 服務(wù)網(wǎng)站上(你可以自己建立一個 OpenID 服務(wù)網(wǎng)站,也可以選擇一個可信任的 OpenID 服務(wù)網(wǎng)站來完成注冊)。
與OpenID同屬性的身份識別服務(wù)商還有ⅥeID,ClaimID,CardSpace,Rapleaf,Trufina ID Card等,其中ⅥeID通用賬戶的應(yīng)用最為廣泛。
Spring Security和Shiro
相同點:
1:認證功能
2:授權(quán)功能
3:加密功能
4:會話管理
5:緩存支持
6:rememberMe功能.......
不同點:
優(yōu)點:
1:Spring Security基于Spring開發(fā),項目中如果使用Spring作為基礎(chǔ),配合Spring Security做權(quán)限更加方便,而Shiro需要和Spring進行整合開發(fā)
2:Spring Security功能比Shiro更加豐富些,例如安全防護
3:Spring Security社區(qū)資源比Shiro豐富
缺點:
1:Shiro的配置和使用比較簡單,Spring Security上手復(fù)雜
2:Shiro依賴性低,不需要任何框架和容器,可以獨立運行,而Spring Security依賴于Spring容器
總結(jié)
以上是生活随笔為你收集整理的java shiro security_安全框架Shiro和SpringSecurity的比较的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 南通大学python期末考试试卷答案_南
- 下一篇: 漂亮的html页面源码_爬虫数据分析之h