<!--shiro 的web過(guò)濾器-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"></property>
<!--loginUrl認(rèn)證提交地址 ,如果沒(méi)有認(rèn)證將會(huì)請(qǐng)求此地址進(jìn)行認(rèn)證,
請(qǐng)求地址由formAuthenticationFilter進(jìn)行表單認(rèn)證-->
<property name="loginUrl" value="/login.action"></property>
<!--認(rèn)證成功后,跳轉(zhuǎn)路徑 建議不配置,認(rèn)證成功后自動(dòng)到上一個(gè)請(qǐng)求路徑-->
<!--<property name="successUrl" value="/first.action"></property>-->
<!--通過(guò)unauthorizedUrl指定沒(méi)有權(quán)限操作時(shí)跳轉(zhuǎn)頁(yè)面-->
<property name="unauthorizedUrl" value="/refuse.jsp"></property>
<!--過(guò)濾器定義,從上到下順序執(zhí)行,一般將/** 放在最下面-->
<property name="filterChainDefinitions">
<value>
<!--/**=anon 所有url都可以匿名訪問(wèn)-->
<!--/**=anon-->
<!--靜態(tài)資源進(jìn)行匿名訪問(wèn)-->
/images/**=anon
/js/**=anon
/styles/**=anon
<!--logoutFilter 退出自動(dòng)清除session-->
/logout.action=logout
<!-- /** = authc 所有url都必須認(rèn)證通過(guò)才可以訪問(wèn)-->
/** = authc
<!-- /** = anon所有url都可以匿名訪問(wèn) -->
</value>
</property>
</bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="customRealm"></property>
</bean>
<bean id="customRealm" class="cn.tencent.shiro.shiro.CustomRealm">
<property name="credentialsMatcher" ref="credentialsMatcher"></property>
</bean>
<!--憑證匹配器-->
<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="md5"></property>
<property name="hashIterations" value="1"></property>
</bean>
自定義Realm
public class CustomRealm extends AuthorizingRealm {
//注入service
@Autowired
private SysService sysService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
// 設(shè)置realm的名稱
@Override
public void setName(String name) {
super.setName("customRealm");
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//1 從token中取出用戶名
String userCode = (String) token.getPrincipal();
//2 數(shù)據(jù)庫(kù)中獲取
SysUser sysUser = sysService.findSysUserByUserCode(userCode);
if (sysUser == null) {
return null;
}
String password = sysUser.getPassword();
String salt = sysUser.getSalt();
ActiveUser activeUser = new ActiveUser();
activeUser.setUserid(sysUser.getId());
activeUser.setUsercode(sysUser.getUsercode());
activeUser.setUsername(sysUser.getUsername());
List<SysPermission> menuLists = null;
try {
menuLists = sysService.findMenuListByUserId(sysUser.getId());
} catch (Exception e) {
e.printStackTrace();
}
activeUser.setMenus(menuLists);
// password
// 如果查詢到了,返回AuthenticationInfo
// 如果密碼不匹配,拋出IncorrectCredentialsException
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(activeUser,
sysUser.getPassword(), ByteSource.Util.bytes(salt), this.getName());
return simpleAuthenticationInfo;
}
}
login.action處理
@RequestMapping(value = "login.action")
public String login(HttpServletRequest request) throws Exception {
//登錄失敗從request中獲取認(rèn)證異常信息 shiroLoginFailure 就是shiro異常類的全限定名
String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
//根據(jù)shiro返回的異常類型路徑判斷,拋出指定異常信息
if (exceptionClassName != null) {
if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
throw new CustomException("賬號(hào)不存在");
} else if (IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
throw new CustomException("賬號(hào)密碼錯(cuò)誤");
} else {
throw new Exception();
}
}
////此方法不處理登陸成功(認(rèn)證成功),shiro認(rèn)證成功會(huì)自動(dòng)跳轉(zhuǎn)到上一個(gè)請(qǐng)求路徑
//login.jsp界面
return "login";
}