前面我们学习了Shiro的基本架构,以及Shiro的认证和授权机制,今天我们聊聊Shiro在xml文件中的配置

Shiro的配置主要有如下几个部分:

  • 对象和属性的定义与配置
  • URL的过滤器配置
  • 静态用户配置
  • 静态角色配置

其中,用户与角色一般有后台操作,其数据是动态的,所以xml的配置主要包含前两项。

我们主要讲解Spring XML的文件配置。

Shiro对象的配置

主要是对Shiro各个组件的实现进行定义配置

1
2
3
4
5
6
7
<bean id="securityManager" class="org.apache.shiro.mgt.DefaultSecurityManager">
<property name="cacheManager" ref="cacheManager"/>
<property name="sessionMode" value="native"/>
<!-- Single realm app. If you have multiple realms, use the 'realms' property instead. -->
<property name="realm" ref="myRealm"/>
<property name="sessionManager" ref="sessionManager"/>
</bean>

Shiro过滤器的配置

Shiro主要是通过URL(粗粒度的权限控制)过滤来进行安全管理,这里的配置便是指定具体授权规则定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login.jsp"/>
<property name="successUrl" value="/home.jsp"/>
<property name="unauthorizedUrl" value="/unauthorized.jsp"/> -->
<property name="filterChainDefinitions">
<value>
<!--some example chain definitions:-->
/admin/** = authc, roles[admin]
/docs/** = authc, perms[document:read]
/** = authc
<!--more URL-to-FilterChain definitions here-->
</value>
</property>
</bean>
URL过滤器配置说明

Shiro可以通过配置文件实现基于URL的授权验证。FilterChain定义格式:
URL_Ant_Path_Expression = Path_Specific_Filter_Chain
每个URL配置,表示匹配该URL的应用程序请求将由对应的过滤器进行验证。
例如:

1
2
3
4
5
6
7
[urls]
/index.html = anon
/user/create = anon
/user/** = authc
/admin/** = authc, roles[administrator]
/rest/** = authc, rest
/remoting/rpc/** = authc, perms["remote:invoke"]
URL表达式说明

1、URL目录是基于HttpServletRequest.getContextPath()此目录设置
2、URL可使用通配符,**代表任意子目录
3、Shiro验证URL时,URL匹配成功便不再继续匹配查找。所以要注意配置文件中的URL顺序,尤其在使用通配符时。

Filter Chain定义说明

1、一个URL可以配置多个Filter,使用逗号分隔
2、当设置多个过滤器时,全部验证通过,才视为通过
3、部分过滤器可指定参数,如perms,roles

Shiro与Spring整合

在web.xml中添加shiro过滤器
1
2
3
4
5
6
7
8
9
10
11
<!-- Shiro filter-->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在Spring的applicationContext.xml中添加shiro配置

1、添加shiroFilter定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!-- Shiro Filter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/login" />
<property name="successUrl" value="/user/list" />
<property name="unauthorizedUrl" value="/login" />
<property name="filterChainDefinitions">
<value>
/login = anon
/user/** = authc
/role/edit/* = perms[role:edit]
/role/save = perms[role:edit]
/role/list = perms[role:view]
/** = authc
</value>
</property>
</bean>
<!--
shiroFilter 中 loginUrl 为登录页面地址,
successUrl 为登录成功页面地址(如果首先访问受保护 URL 登录成功,则跳转到实际访问页面),
unauthorizedUrl 认证未通过访问的页面(前面提到的“未经授权页面”)。
-->

2、添加securityManager定义

1
2
3
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealm" />
</bean>

3、添加realm定义

1
<bean id=" myRealm" class="com...MyRealm" />
实现MyRealm:继承AuthorizingRealm,并重写认证授权方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class MyRealm extends AuthorizingRealm{
private AccountManager accountManager;
public void setAccountManager(AccountManager accountManager) {
this.accountManager = accountManager;
}
/**
* 授权信息
*/
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
String username=(String)principals.fromRealm(getName()).iterator().next();
if( username != null ){
User user = accountManager.get( username );
if( user != null && user.getRoles() != null ){
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
for( SecurityRole each: user.getRoles() ){
info.addRole(each.getName());
info.addStringPermissions(each.getPermissionsAsString());
}
return info;
}
}
return null;
}
/**
* 认证信息
*/
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken ) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
String userName = token.getUsername();
if( userName != null && !"".equals(userName) ){
User user = accountManager.login(token.getUsername(),
String.valueOf(token.getPassword()));
if( user != null )
return new SimpleAuthenticationInfo(
user.getLoginName(),user.getPassword(), getName());
}
return null;
}
}