深入浅出学Shiro(二)--授权认证

    授权即访问控制,它将判断用户在应用程序中对资源是否拥有相应的访问权限。如,判断一个用户有查看页面的权限,编辑数据的权限,拥有某一按钮的权限,以及是否拥有打印的权限等等。

    认证通过后接受 Shiro授权检查,授权验证时,需要判断当前角色是否拥有该权限。只有授权通过,才可以访问受保护 URL 对应的资源,否则跳转到“未经授权页面”。

 

首先来结合一个实例来说明:

 

上篇博客(深入浅出学Shiro(一)--登录认证)已经讲解了配置,下面我们直接来看代码实现

 

shiro认证成功后,跳转到main.jsp页面


                

Main.jsp页面内容:

<body>
		<ul>
			<li>
				<h2>
					<a target="_self" href="user.do?myjsp">访问myjsp页面</a>
				</h2>
			</li>
			<li>
				<h2>
					<a target="_self" href="user.do?notmyjsp">访问notmyjsp页面(无权访问)</a>
				</h2>
			</li>
			<li>
				<h2>
					<a target="_self" href="user.do?visitAdminPage">访问admin页面</a>
				</h2>
			</li>
			
			<li>
				<h2>
					<a target="_self" href="user.do?visitByAnnotation">通过注解访问页面(无权访问)</a>
				</h2>
			</li>
		</ul>
	</body>

当点击页面某个链接时,跳转到相应的controller

@Controller
@RequestMapping(value="user")
public class UserController {
	/**
	 * 访问myjsp页面,有权限
	 * @return
	 */
	@RequestMapping(params = "myjsp")
	public String home() {
		/*通过SecurityUtils工具类,获取当前的用户*/
		Subject currentUser = SecurityUtils.getSubject();
		
		// 回调 doGetAuthorizationInfo,进行授权验证
		if(currentUser.isPermitted("user.do?myjsp")){
			return "my";
		}else{
			return "error/noperms";
		}
	}

当程序执行到currentUser.isPermitted方法时,调用到publicclass DelegatingSubject implements Subject类的isPermitted方法。

 

附源码:

public boolean isPermitted(String permission) {
        return hasPrincipals() && securityManager.isPermitted(getPrincipals(), permission);
    }


通过上篇博客我们知道,这时SecurityManager会委托给Realm,故接下来执行我们自定义的Realm

@Service("monitorRealm")
public class MonitorRealm extends AuthorizingRealm {

	//获取授权信息 
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		/* 这里编写授权代码 */
		Set<String> roleNames = new HashSet<String>();
	    Set<String> permissions = new HashSet<String>();
	    roleNames.add("admin");
	    permissions.add("user.do?myjsp");
	    permissions.add("login.do?main");
	    permissions.add("login.do?logout");
	    //对比的过程
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
	    info.setStringPermissions(permissions);
		return info;
	}
}

对比的过程中如果存在则正确返回,否则返回error

 

补充:

 

结合上篇博客的配置还想要多说两句

 

其一:SpringMVC拦截

 

这部分配置,是配置SpringMVC的拦截页面,看了这个配置相信大家也就明白了为什么我们访问的页面要加上.do(user.do?notmyjsp)吧!

<servlet-mapping>
		<servlet-name>springMvc</servlet-name>
		<!-- 只拦截带do后缀的 -->
		<!-- <url-pattern>*.do</url-pattern> -->
		<!-- 将springmvc的匹配表达式修改为所有的页面均拦截 -->
		<url-pattern>/</url-pattern> 

</servlet-mapping>


其二:ShiroFilter拦截

 

这部分配置是配置的ShiroFilter,也就是shiro拦截哪些页面。

<!-- Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的、自定义的过滤器的执行-->  
	<!-- Shiro Filter -->  
	<filter>
		<filter-name>shiroFilter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
		<init-param>
			<param-name>targetFilterLifecycle</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<!-- shiro只拦截如下的后缀 -->
	<filter-mapping>
		<filter-name>shiroFilter</filter-name>
		<url-pattern>*.action</url-pattern>
	</filter-mapping>
	<filter-mapping>
		<filter-name>shiroFilter</filter-name>
		<url-pattern>*.do</url-pattern>
	</filter-mapping>
	<filter-mapping>
		<filter-name>shiroFilter</filter-name>
		<url-pattern>*.jsp</url-pattern>
	</filter-mapping>


其三:Shiro过滤链的定义(是否需要登录认证)

 

以下这部分配置,是配置访问的页面是否需要验证,即登录后才可以访问。举例说明:访问后缀名为.action的页面,我可以直接访问到,那么如果我访问.do的页面,则会自动跳转到登录页,需要我们首先登录后才可以访问,这些就与我们配置的过滤链相关。

<property name="filterChainDefinitions">
			<value>
			 <!-- Shiro 过滤链的定义-->   
        <!--此处可配合这篇文章来理解各个过滤连的作用http://blog.csdn.net/jadyer/article/details/12172839-->
				<!-- 
					Anon:不指定过滤器 
					Authc:验证,这些页面必须验证后才能访问,也就是我们说的登录后才能访问。
					-->
					 <!--下面value值的第一个'/'代表的路径是相对于HttpServletRequest.getContextPath()的值来的 -->   
					<!--anon:它对应的过滤器里面是空的,什么都没做,这里.do和.jsp后面的*表示参数,比方说login.jsp?main这种 -->   
        <!--authc:该过滤器下的页面必须验证后才能访问,它是Shiro内置的一个拦截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter-->   
				
				/login.jsp* = anon
				/login.do* = anon
				/index.jsp*= anon
				/error/noperms.jsp*= anon
				/*.jsp* = authc
				/*.do* = authc
			</value>
		</property>


这些过滤器分为两组,一组是认证过滤器,一组是授权过滤器。其中anon,authcBasic,auchc,user是第一组,

perms,roles,ssl,rest,port是第二组

可参考:http://blog.csdn.net/hxpjava1/article/details/7035724


扩展:

 

Shiro支持三种方式实现授权过程:

 

编码实现

注解实现

JSPTaglig实现

 

编程式:通过写if/else授权代码块完成(以上实例即使用编程式完成): 

Subject subject = SecurityUtils.getSubject();  
if(subject.hasRole(“admin”)) {  
    //有权限  
} else {  
    //无权限  
}   


注解式:通过在执行的Java方法上放置相应的注解完成:

@RequiresRoles("admin")  
public void hello() {  
    //有权限  
}   

没有权限将抛出相应的异常;

JSP标签:在JSP/GSP页面通过相应的标签完成: 

<shiro:hasPermission name="user:create">  
	<a href="createUser.jsp">Create a new User</a>  
</shiro:hasPermission>  


总结:


    无论是Shiro的登录认证还是授权,其实都是结合Subject,SecurityManager和Realms这三者的关系来实现的,理解了三者的关系Shiro也就学会了。Subject,当前用户;SecurityManager,外观的作用,其内部为我们封装了实现好的功能;Realms,Shiro和真实Dao操作的桥梁,以下这张图很形象的展示了三者的关系。

                   


  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值