shiro許可權配置的細節問題&認證
細節:
---[urls]部分配置,其格式是 url=攔截器【引數】 ,攔截器【引數】
---如果當前請求的 url 匹配 【urls】 部分或者某個url模式,將會執行配置的攔截器
---anon(anonymous)攔截器表示匿名訪問(即不需要登陸驗證)
---authc(authentication)攔截器的表示需要身份認證之後才能訪問
<property name="filterChainDefinitions"> <value> /login.jsp = anon # everything else requires authentication: /** = authc </value> </property>
/login.jsp = anon # everything else requires authentication: /** = authc /user.jsp = anon
此時上面的會覆蓋下面的user.jsp 無法訪問
認證:
步驟:
1.獲取當前subject, SecurityUtils.getSubject();
2.測試當前使用者是否已經被認證,即是否已經登陸, currentUser.isAuthenticated()
3.若沒有認證則/把使用者名稱和密碼封裝為UsernamePasswordToken物件
-建立一個表單
-把請求提交到spriingmvc 的handler
-獲取使用者和密碼
4.執行登陸 currentUser.login(token);
5.自定義Relam方法,從資料庫中獲取相應的記錄,返回給Shiro
-實際上是需要整合org.apache.shiro.realm.AuthenticatingRealm
-實現 doGetAuthenticationInfo() 方法
6.有shiro完成對密碼的比對
測試使用到的檔案:
下面開始程式碼過程:
login.jsp頁面的登陸標誌程式碼:
login <form action="shiro/login" method="post"> username:<input type="text" name="username"> password:<input type="password" name="password"> <input type="submit" value="submit"> </form>
在application中
<property name="filterChainDefinitions"> <value> /login.jsp = anon /shiro/login = anon # everything else requires authentication: /** = authc </value> </property>
ShiroHandler.java
@Controller @RequestMapping("/shiro") public class ShiroHandler { @RequestMapping("/login") public String login(@RequestParam("username")Stringusername,@RequestParam("password") String password){ Subject currentUser = SecurityUtils.getSubject(); if (!currentUser.isAuthenticated()) { //把使用者名稱和密碼封裝為UsernamePasswordToken物件 UsernamePasswordToken token = newUsernamePasswordToken(username, password); token.setRememberMe(true); try { //執行登陸 currentUser.login(token); }catch (AuthenticationException ae) { System.out.println("登陸失敗" +ae.getMessage()); } } 成功之後做重定向 return "redirect:/list.jsp"; } }
在applicationContext中需要掃描這個類的包
ShiroRealm.java
做登陸驗證實現下面的介面即可
doGetAuthenticationInfo(AuthenticationToken arg0)的arg0是指就是UsernamePasswordToken token = new UsernamePasswordToken(username, password);
public class ShiroRealm extends AuthenticatingRealm { @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException { System.out.println("doGetAuthenticationInfo" + arg0); //1.把AuthenticationToken轉為UsernamePasswordToken UsernamePasswordTokenupToken = (UsernamePasswordToken) arg0; //2.從UsernamePasswordToken獲取username String username = upToken.getUsername(); //3.呼叫資料庫的方法,從資料庫查詢username對應的使用者記錄 System.out.println("從資料庫中獲取username:" + username); //4.若使用者不存在可以丟擲異常 UnKnownAccountException異常 if("unknow".equals(username)){ throw new UnknownAccountException("username 不存在"); } //5.根據使用者資訊的清空決定是否需要丟擲其他的異常 if("monster".equals(username)){ throw new LockedAccountException("使用者被鎖定"); } //6.根據使用者的情況來構建AuthenticationInfo並且返回 //以下資訊是從資料庫中獲取的 //principal:認證的實體資訊,可以是username,也可以是資料表對應的實體物件 Object principal = username; //credentials:密碼 Object credentials = "1234"; //realmName:當前realm物件為name,呼叫父類的getName()方法即可 String realmName = getName(); SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credentials, realmName); return info; } }
當我們輸入密碼為1234,以及其他為username(除了上圖的兩個)
此時我們就有許可權對其他的頁面進行測試
出錯之後的異常還是會列印的
此時我們需要登出的操作
list.jsp
<body> list. <a href="shiro/logout">Logout</a> </body>
在applicationContext.xml檔案中:
<!-- 配置那些頁面需要受保護,以及訪問這些頁面需要的的許可權 1)anon 可以被匿名訪問 2)authc 必須認證即登陸後才可以訪問的頁面 3).logout登出 --> <property name="filterChainDefinitions"> <value> /login.jsp = anon /shiro/login = anon /shiro/logout = logout # everything else requires authentication: /** = authc </value> </property>
但我們點選這個超連結的 時候就會立馬退出來到login.jsp頁面中