細節:
---[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")String username,@RequestParam("password") String password){ Subject currentUser = SecurityUtils.getSubject(); if (!currentUser.isAuthenticated()) { //把用戶名和密碼封裝為UsernamePasswordToken對象 UsernamePasswordToken token = new UsernamePasswordToken(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 UsernamePasswordToken upToken = (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頁面中