僅供參考
僅供參考
登錄部分
代碼:
@RequestMapping(value = "/login", method = RequestMethod.GET) @ResponseBody public Map<String, Object> login(HttpServletRequest request) { Map<String, Object> resultMap = new LinkedHashMap<String, Object>(); try { ShiroToken token = new ShiroToken("admin", "21232f297a57a5a743894a0e4a801fc3"); token.setRememberMe(false); SecurityUtils.getSubject().login(token); ShiroToken token2 = (ShiroToken) SecurityUtils.getSubject().getPrincipal(); logger.info(token2.getUsername() + "," + token2.getPswd()); resultMap.put("status", 200); resultMap.put("message", "登錄成功"); /** * 獲取登錄之前的地址 */ SavedRequest savedRequest = WebUtils.getSavedRequest(request); String url = null; if (null != savedRequest) { url = savedRequest.getRequestUrl(); } // 跳轉地址 resultMap.put("back_url", url); } catch (DisabledAccountException e) { resultMap.put("status", 500); resultMap.put("message", "帳號已經禁用。"); } catch (Exception e) { resultMap.put("status", 500); resultMap.put("message", "帳號或密碼錯誤"); } return resultMap; }
注意幾點:
1、登錄密碼記得加密,一般存在數據庫中的密碼是加密過的。
2、真正開始執行登錄操作的是SecurityUtils.getSubject().login(token),這個方法會調用org.apache.shiro.realm.AuthorizingRealm的doGetAuthenticationInfo方法進行登錄認證:
3、出錯異常記得捕獲
登錄驗證部分
代碼如下:
@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) { ShiroToken token = (ShiroToken) arg0; String username = token.getUsername(); // 根據username從數據庫查找用戶,得到密碼 // 假設找到的用戶如下 // User user = userService.findByUsername(username) User user = new User(); user.setName(username); user.setPassword("21232f297a57a5a743894a0e4a801fc3"); // 數據庫中的密碼md5加密的 if (null == user) { throw new AccountException("username is not exist"); } else if (!user.getPassword().equals(token.getPswd())) { throw new AccountException("password is not right"); } else { // 登陸成功 logger.info("{} login success.", username); } return new SimpleAuthenticationInfo(arg0, user.getPassword(), username); }
注意幾點:
1、一般會根據username從數據庫中查找該用戶,得到密碼
2、進行密碼校驗,判斷一致性
3、根據獲取到的用戶信息,也可以進行其它判斷,如用戶是否激活,是否被禁用等
授權部分
代碼如下:
@Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) { ShiroToken token = (ShiroToken) SecurityUtils.getSubject().getPrincipal(); String username = token.getUsername(); logger.info(username + "授權..."); // 從數據庫中查找該用戶的角色和權限 SimpleAuthorizationInfo sainfo = new SimpleAuthorizationInfo(); Set<String> roles = new HashSet<String>(); roles.add("admin"); //roles.add("role1"); Set<String> permissions = new HashSet<String>(); permissions.add("add"); permissions.add("delete"); sainfo.setRoles(roles); sainfo.setStringPermissions(permissions); return sainfo; }
注意,一般是根據用戶名從數據庫中查找該用戶的角色和權限,進行授權;當然其它途徑也是可以的,如webservice接口,配置文件等獲取用戶權限。
權限攔截配置
如下:
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"></property> <property name="loginUrl" value="/security/view/login"></property> <property name="successUrl" value="/successUrl"></property> <!-- 用戶訪問未對其授權的資源時,所顯示的連接 --> <property name="unauthorizedUrl" value="/unauthorizedUrl"></property> <property name="filters"> <map> <entry key="anyRoles"> <bean class="cn.edu.hdu.ssd.core.shiro.AnyRolesAuthorizationFilter" /> </entry> </map> </property> <property name="filterChainDefinitions"> <value> /security/**=anon /test/**=roles[role1] /users/**=anyRoles[admin,role1] /**=authc </value> </property> </bean>
根據用戶的角色或權限來配置對應匹配的訪問路徑;
訪問路徑匹配任意角色
默認情況下,配置權限控制的時候,如
/test/**=roles[role1,admin]
結果是需要用戶同時擁有role1和admin權限才能訪問/test/**路徑,這往往不符合我們的需求,
大部分情況,我們希望的是用戶擁有role1和admin任一角色即可。
那么可以這樣修改,編寫一個過濾器:
public class AnyRolesAuthorizationFilter extends AuthorizationFilter { // private Logger logger = LoggerFactory.getLogger(ShiroCasAuthFilter.class); @Override protected boolean isAccessAllowed(ServletRequest req, ServletResponse resp, Object mappedValue) throws Exception { Subject subject = getSubject(req, resp); String[] rolesArray = (String[]) mappedValue; if (rolesArray == null || rolesArray.length == 0) { return true; } for (int i = 0; i < rolesArray.length; i++) { if (subject.hasRole(rolesArray[i])) { return true; } } return false; } }
配置shiroFilter bean的filters屬性,如下,
<property name="filters"> <map> <entry key="anyRoles"> <bean class="cn.edu.hdu.ssd.core.shiro.AnyRolesAuthorizationFilter" /> </entry> </map> </property>
最后,權限攔截配置可以這樣配:
/test/**=anyRoles[admin,role1]
示例源碼參考
https://github.com/peterchenhdu/spring-shiro-demo
