shiro学习02-用户校验及权限验证基础

下面是摘自官方文档中的用户校验和权限检查,我觉得还是很有必要看一看。

一、用户校验

这一节对应于官方文档的地址是:http://shiro.apache.org/java-authentication-guide.html,主要介绍shiro的用户验证的部分。

在这一节中主要的名词有如下:

Subject(类比于用户),Principal(类似于用户名),Credentials(类似密码),Realm(类似于我们的数据库,存储用户的相关信息)

第一步:收集用户的principal和credentials(也就是用户名和密码),代码如下:

//Example using most common scenario:
//String username and password.  Acquire in
//system-specific manner (HTTP request, GUI, etc)

UsernamePasswordToken token =
 new UsernamePasswordToken( username, password );

//”Remember Me” built-in, just do this:
token.setRememberMe(true);

这里我们使用了usernamepasswordToken,这个是最长使用的token,通过校验用户名和密码是否匹配来实现对用户的校验。

第二步:提交princapal和credentials到校验系统。代码如下:

//With most of Shiro, you'll always want to make sure you're working with the currently executing user, referred to as the subject
Subject currentUser = SecurityUtils.getSubject();

//Authenticate the subject by passing
//the user name and password token
//into the login method
currentUser.login(token);

我们通过调用SecurityUtils来获得一个Subject,也就是我们通常说的用户,然后这个用户调用login方法,如果不出任何异常的话,表示校验通过。

第三步、捕获校验时的异常

当用户名和密码不一致时,将会抛出异常(至于到底是那个类的哪个方法抛得异常,先不用管),代码如下:

try {
    currentUser.login(token);
} catch ( UnknownAccountException uae ) { ...
} catch ( IncorrectCredentialsException ice ) { ...
} catch ( LockedAccountException lae ) { ...
} catch ( ExcessiveAttemptsException eae ) { ...
} ... catch your own ...
} catch ( AuthenticationException ae ) {
    //unexpected error?
}

然后根据捕获的异常进行判断,比如我们在开发中会跳到不同的页面。

Remember Me  的说明:

上面的代码中有个

token.setRememberMe(true);

这个的字面意思是记住我,这个的意思是先不管我是不是正确的用户和密码,你先记住我,他的内部逻辑是发送了一个cookie到浏览器,然后等下一次再访问的时候,就可以通过这个cookie知道我“有可能”是谁了,这里说的是有可能,因为setRememberMe并不一定是通过校验了,可能他的校验失败了,所以只能是通过这个cookie知道可能是谁。

RememberMe 和 Authenticated

在shiro中有两个方法,一个是isAuthenticated,一个是isRemembered,两者是不同的,前者的逻辑是更加严格的检验,而后者只是说明有可能是谁,而没有证明就是真实的用户。这个我们在淘宝上有相同的例子,当我们重复的使用一个浏览器访问淘宝时,即使我们不登录他的最上面也显示我们的用户名,即使是另一个人在使用同一个浏览器访问淘宝时也是显示的我们的名字,显然另一个人不是你自己,所以尽管通过发送cookie到浏览器记住了可能的用户,但是在进行一些操作,比如查看购物车时,淘宝要求必须登录之后才能操作,也就是必须证明你是谁,也就是authenticating yourself。

 二、权限验证

与权限验证相关的术语有:permissions,也就是权限;role,也就是角色;user,用户。

·权限:permission,这个是权限验证模块中粒度最小的名词,所有的权限验证都是建立在permission上的。permission定义了可以做什么事情,比如删除某个记录,更新某个记录,查询某个记录等。

·角色:这个是为了方便用户与权限之间的多对多的联系而采取的办法。一个用户有多个角色,一个角色有多个权限,使用角色来管理角色的好处就是方便权限的管理。

·用户这个概念和之前说的一样。

关于权限的验证在编码中的实现有下面的三种:

·programmatically,也就是通过编码实现,比如通过if else进行判断,然后根据逻辑进行操作。

·annotations,使用标签,shiro中提供了很多的标签供使用,但是对标签的使用必须依靠aop,比如使用spring的aop或者是使用aspectj的,我个人不推荐使用这个。

·jsp标签,就像我们使用的标准标签库一样,shiro也提供了一套自己的标签。

1、编码实现

编码实现也有好几种,比如基于角色的,基于权限的,基于字符串的。这里面最不推荐使用的就是基于角色的,因为角色有可能是后期生成的,可能会删除某个角色,需要修改源码,可能会造成很大的麻烦,

下面是官网文档中的基于权限授权的的代码

Subject currentUser =
    SecurityUtils.getSubject();

Permission printPermission = 
new PrinterPermission(“laserjet3000n”,“print”);

If (currentUser.isPermitted(printPermission)) {
    //do one thing (show the print button?)‏
} else {
    //don’t show the button?
}

2、基于注解,因为我本人不提倡使用这个,所以没有记录

3、基于jsp标签,下面是官网文档中的一个例子

<%@ taglib prefix=“shiro” uri=http://shiro.apache.org/tags %>
<html>
<body>
    <shiro:hasPermission name=“users:manage”>
        <a href=“manageUsers.jsp”>
            Click here to manage users
        </a>
    </shiro:hasPermission>
    <shiro:lacksPermission name=“users:manage”>
        No user management for you!
    </shiro:lacksPermission>
</body>
</html>

shiro的标签不是很多,都在这个页面上:http://shiro.apache.org/jsp-tag-library.html,下面贴出来

  • <shiro:guest/> - Displays body content only if the current Subject IS NOT known to the system, either because they have not logged in or they have no corresponding 'RememberMe' identity. It is logically opposite to the 'user' tag.
  • <shiro:user/> - Displays body content only if the current Subject has a known identity, either from a previous login or from 'RememberMe' services. Note that this is semantically different from the 'authenticated' tag, which is more restrictive. It is logically opposite to the 'guest' tag.
  • <shiro:principal/> - Displays the user's principal or a property of the user's principal.
  • <shiro:hasPermission/> - Displays body content only if the current Subject (user) 'has' (implies) the specified permission (i.e the user has the specified ability).
  • <shiro:lacksPermission/> - Displays body content only if the current Subject (user) does NOT have (not imply) the specified permission (i.e. the user lacks the specified ability)
  • <shiro:hasRole/> - Displays body content only if the current user has the specified role.
  • <shiro:lacksRole/> - Displays body content only if the current user does NOT have the specified role (i.e. they explicitly lack the specified role)
  • <shiro:hasAnyRoles/> - Displays body content only if the current user has one of the specified roles from a comma-separated list of role names
  • <shiro:authenticated/> - Displays body content only if the current user has successfully authenticated during their current session. It is more restrictive than the 'user' tag. It is logically opposite to the 'notAuthenticated' tag.
  • <shiro:notAuthenticated/> - Displays body content only if the current user has NOT succesfully authenticated during their current session. It is logically opposite to the 'authenticated' tag.

相关推荐