上一章節我給大家講了如何設計擴展動態修改shiro的資源而不用重啓項目,這個章節我講的是如何自定義我們的特殊過濾器
講到認證這一塊,我們經常用到就是authc,roles,perms這三個標籤,說到底標籤其實就是一個map的key,然後指向filter實例,相信大家都懂這個了,所以我就不囉嗦,下面我們看看roles的filter實現類
package org.apache.shiro.web.filter.authz;
import java.io.IOException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.CollectionUtils;
// Referenced classes of package org.apache.shiro.web.filter.authz:
// AuthorizationFilter
public class RolesAuthorizationFilter extends AuthorizationFilter
{
public RolesAuthorizationFilter()
{
}
public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws IOException
{
Subject subject = getSubject(request, response);
String rolesArray[] = (String[])(String[])mappedValue;
if(rolesArray == null || rolesArray.length == 0)
{
return true;
} else
{
java.util.Set roles = CollectionUtils.asSet(rolesArray);
return subject.hasAllRoles(roles);
}
}
}
我們可以看到其實這個roles的filter是通過subject.hasAllRoles(roles)判斷是否滿足所有權限,但是我們真實項目中,很多時候用戶只要滿足其中一個角色即可認爲是授權認證成功,所以這個時候,我們首先想到的是再寫個filter吧,那我們下面就寫個滿足任一角色即可放行的授權認證類
public class RoleAuthorizationFilter extends AuthorizationFilter {
public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws IOException {
Subject subject = getSubject(request, response);
String[] rolesArray = (String[]) mappedValue;
if (rolesArray == null || rolesArray.length == 0) {
// no roles specified, so nothing to check - allow access.
return true;
}
Set<String> roles = CollectionUtils.asSet(rolesArray);
for (String role : roles) {
if (subject.hasRole(role)) {
return true;
}
}
return false;
}
}
很簡單的樣子,其實就是從RolesAuthorizationFilter這個類copy一份代碼過來,然後把subject.hasAllRoles()換成遍歷調用subject.hasRole()方法,如存在任一角色則返回true即可
最後我們把這個filter要配置到主過濾器裏,並且定義標籤爲role
<!-- 過濾鏈配置 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/" />
<property name="successUrl" value="/cms/index.do" />
<property name="unauthorizedUrl" value="/" />
<property name="filters">
<map>
<entry key="role">
<bean
class="com.silvery.security.shiro.filter.RoleAuthorizationFilter" />
</entry>
<entry key="authc">
<bean
class="com.silvery.security.shiro.filter.SimpleFormAuthenticationFilter" />
</entry>
</map>
</property>
</bean>
象上述配置就是使用自定義過濾器,如: /test/** = role[admin] 或者 /test/** = role[admin,user] 這樣用戶擁有任一定義的角色都能認證成功
由上述的自定義filter可以看出,我們在shiro上增加其他filter並不難,所以如果需要增加其他filter就不需要擔心實現不了...