簡單三步理解Shiro許可權驗證/登入
阿新 • • 發佈:2019-01-02
通過請求方式來判斷是初始請求還是驗證請求 一、 @RequestMapping(value ="/login", method =RequestMethod.GET)publicString showLoginPage(){return"user/login";}@RequestMapping(value ="/login", method =RequestMethod.POST)publicString submitLoginForm(User user,HttpServletRequest request,Model model){String errorClassName =(String)request .getAttribute("shiroLoginFailure");String authticationError =null;if(UnknownAccountException.class.getName().equals(errorClassName)){ authticationError ="使用者名稱/密碼錯誤";}elseif(IncorrectCredentialsException.class.getName().equals( errorClassName)){ authticationError="使用者名稱/密碼錯誤";}elseif(errorClassName !=null){ authticationError ="未知錯誤:"+ errorClassName;} model.addAttribute("authticationError", authticationError);return showLoginPage();} Shiro配置檔案中進行請求攔截管理 二、 ------------------------------------------------------第一種配置方式---------------------------------------------------
<!-- 憑證匹配器 這裡簡單寫了一個無需加密的匹配 --><beanid="credentialsMatcher"class="com.zhu.prototype.shiro.credential.PlainPasswordMatcher"></bean><beanid="jdbcRealm"class="org.apache.shiro.realm.jdbc.JdbcRealm"><propertyname="credentialsMatcher"ref="credentialsMatcher"></property><propertyname="authenticationQuery"value="select password from user where username = ?"></property><propertyname="dataSource"ref="dataSource"></property></bean><!-- 安全管理器 DefaultWebSecurityManager預設使用ServletContainerSessionManager來管理session--><beanid="securityManager"class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><propertyname="realms"><list><refbean="jdbcRealm"/></list></property></bean><!-- 基於Form表單的身份驗證過濾器 --><beanid="formAuthenticationFilter"class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter"><propertyname="usernameParam"value="username"/><propertyname="passwordParam"value="password"/><propertyname="loginUrl"value="/login"/> --------------------- 釋放login請求 <propertyname="successUrl"value="/news/newsList"></property> -----------------------驗證成功時釋放的請求 </bean>
------------------------------------------------------第二種配置方式(chang---------------------------------------------------
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
beans
xmlns
=
"http://www.springframework.org/schema/beans"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"
default-lazy-init
=
"true"
>
<
description
>Shiro安全配置</
description
>
<!-- Shiro's main business-tier object for web-enabled applications -->
<
bean
id
=
"securityManager"
class
=
"org.apache.shiro.web.mgt.DefaultWebSecurityManager"
>
<
property
name
=
"realm"
ref
=
"shiroDbRealm"
/>
<
property
name
=
"cacheManager"
ref
=
"shiroEhcacheManager"
/>
</
bean
>
<!-- 專案自定義的Realm -->
<
bean
id
=
"shiroDbRealm"
class
=
"scau.mis.sexyone.service.member.impl.ShiroDbRealm"
depends-on
=
"staffDao,roleDao"
>
<
property
name
=
"accountService"
ref
=
"accountService"
/>
</
bean
>
<!-- Shiro Filter -->
<
bean
id
=
"shiroFilter"
class
=
"org.apache.shiro.spring.web.ShiroFilterFactoryBean"
>
<
property
name
=
"securityManager"
ref
=
"securityManager"
/
<
property
name
=
"loginUrl"
value
=
"/login"
/>---------釋放login請求
<
property
name
=
"successUrl"
value
=
"/"
/>-----------釋放驗證成功時的請求
<
property
name
=
"filterChainDefinitions"
>
<
value
>
/logout = logout
/account/** = user
/** = authc
</
value
>
</
property
>
</
bean
>
<!-- 使用者授權資訊Cache, 採用EhCache -->
<
bean
id
=
"shiroEhcacheManager"
class
=
"org.apache.shiro.cache.ehcache.EhCacheManager"
>
<
property
name
=
"cacheManagerConfigFile"
value
=
"classpath:security/ehcache-shiro.xml"
/>
</
bean
>
<!-- 保證實現了Shiro內部lifecycle函式的bean執行 -->
<
bean
id
=
"lifecycleBeanPostProcessor"
class
=
"org.apache.shiro.spring.LifecycleBeanPostProcessor"
/>
<!-- AOP式方法級許可權檢查 -->
<
bean
class
=
"org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on
=
"lifecycleBeanPostProcessor"
>
<
property
name
=
"proxyTargetClass"
value
=
"true"
/>
</
bean
>
<
bean
class
=
"org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"
>
<
property
name
=
"securityManager"
ref
=
"securityManager"
/>
</
bean
>
</
beans
>
三、
public
class
ShiroDbRealm
extends
AuthorizingRealm{
protected
AccountService accountService;
@Autowired
public
void
setAccountService(AccountService accountService) {
this
.accountService = accountService;
}
/**
*授權查詢回撥函式, 進行鑑權但快取中無使用者的授權資訊時呼叫.
*/
@Override
protected
AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal();
Staff staff = accountService.findUserByLoginName(shiroUser.loginName);
SimpleAuthorizationInfo info =
new
SimpleAuthorizationInfo();
for
(Role role : staff.getRoles()) {
//基於Role的許可權資訊
info.addRole(role.getName());
//基於Permission的許可權資訊
info.addStringPermissions(role.getPermissionList());
}
return
info;
}
/**
* 登入時呼叫
*/
@Override
protected
AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
throws
AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
Staff staff=
null
;
staff = accountService.findUserByLoginName(token.getUsername());
System.out.println(
"username"
+token.getUsername());
System.out.println(
"password"
+
new
String(token.getPassword()));
if
(staff !=
null
) {
if
(staff.getStatus().equals(
"disabled"
)) {
throw
new
DisabledAccountException();
}
// byte[] salt = Encodes.decodeHex(staff.getSalt());
return
new
SimpleAuthenticationInfo(
new
ShiroUser(staff.getLoginname(), staff.getName()),
staff.getPassword(),
// ByteSource.Util.bytes(salt),
getName());
}
else
{
return
null
;
}
}
}
如果丟擲IncorrectCredentialsException (錯誤的憑證) ---------多數是沒有密碼