序:
在上一篇中,咱們已經對於項目已經做了基本的配置,這一篇文章開始學習Shiro如何對登錄進行驗證。
教學:
一、Shiro配置的簡要說明。
有心人可能注意到了,在上一章的applicationContext.xml配置文件中,包含以下配置。
<!-- 項目自定義的Realm --> <bean id="shiroDbRealm" class="org.shiro.demo.service.realm.ShiroDbRealm" ></bean> <!-- Shiro Filter --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <property name="loginUrl" value="/" /> <property name="successUrl" value="/system/main" /> <property name="unauthorizedUrl" value="/system/error" /> <property name="filterChainDefinitions"> <value> /login = anon /validateCode = anon /** = authc </value> </property> </bean>
大致解釋:
<bean id="shiroDbRealm" class="org.shiro.demo.service.realm.ShiroDbRealm" ></bean>
這個就是指定Shiro驗證用戶登錄的類為自定義的ShiroDbRealm.java。
在Shiro Filter當中:
securityManager:這個屬性是必須的。
loginUrl :沒有登錄的用戶請求需要登錄的頁面時自動跳轉到登錄頁面,不是必須的屬性,不輸入地址的話會自動尋找項目web項目的根目錄下的”/login.jsp”頁面
successUrl :登錄成功默認跳轉頁面,不配置則跳轉至”/”。如果登陸前點擊的一個需要登錄的頁面,則在登錄自動跳轉到那個需要登錄的頁面。不跳轉到此。
unauthorizedUrl :沒有權限默認跳轉的頁面。
filterChainDefinitions : 就是需要驗證的地址的列表,常用的包含anon、authc、perms、roles、user、logout。
/login = anon 代表后綴為/login的鏈接不驗證
/** = authc 代表其它后綴的鏈接都進行登錄驗證,需登錄后才能訪問。
二、新建ShiroDbRealm類
ShiroDbRealm.java
package org.shiro.demo.service.realm; import javax.annotation.Resource; 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.shiro.demo.entity.User; import org.shiro.demo.service.IUserService; public class ShiroDbRealm extends AuthorizingRealm{ @Resource(name="userService") private IUserService userService; protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { return null; } /** * 認證回調函數,登錄時調用. */ protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken authcToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authcToken; User user = userService.getByAccount(token.getUsername()); if (user != null) { return new SimpleAuthenticationInfo(user.getAccount(), user .getPassword(), user.getNickname()); } else { return null; } } }
繼承AuthorizingRealm類,且重寫doGetAuthorizationInfo及doGetAuthenticationInfo方法。
doGetAuthorizationInfo : 驗證當前Subject(可理解為當前用戶)所擁有的權限,且給其授權。在下一章說明。
doGetAuthenticationInfo : 驗證當前Subject登錄。
userService.getByAccount(token.getUsername());是自定義的方法。
(解釋這行的原因是當初在網上看demo的時候,實在沒搞清那些代碼中這一行的意義,后來突然頓悟,請原諒小生愚鈍。)
三、新建UserController.java類
@Controller public class UserController { private static final Log log = LogFactory.getLog(UserController.class); /** * 判斷用戶是否登錄 * @param currUser * @return */ @RequestMapping(value = "/login",method=RequestMethod.POST) public String isLogin(User currUser){ Subject user = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(currUser.getAccount(),currUser.getPassword()); token.setRememberMe(true); try { user.login(token); return "redirect:/main"; }catch (AuthenticationException e) { log.error("登錄失敗錯誤信息:"+e); token.clear(); return "redirect:/login"; } } }
四、新建login.jsp
<form action="<%=basePath%>/login" method="post"> 用戶名:<input type="text" name="account"/> <br/> 密碼:<input type="text" name="password"/><br/> <input type="submit" value="登錄" /> </form>
然后通過SpringMVC訪問到login.jsp頁面,測試Shiro的用戶驗證。