理解Apache Shiro中的主题
毫无疑问,Apache Shiro中最重要的概念是主题。
“主题”只是一个安全术语,它指的是应用程序用户特定于安全的“视图”。Shiro主题实例代表了单个应用程序用户的安全状态和操作。
这些操作包括:
-
身份验证(登录)
-
授权(访问控制)
-
会话的访问
-
注销
我们最初想叫它“用户”,因为这“很有意义”,但我们决定不叫它:太多的应用程序已经有了它们自己的用户类/框架的api,我们不想与它们冲突。
此外,在安全领域,术语“主体”实际上是公认的命名法。
Shiro的API鼓励应用程序采用以主题为中心的编程范式。
在编写应用程序逻辑时,大多数应用程序开发人员都想知道当前执行的用户是谁。
虽然应用程序通常可以通过自己的机制(UserService,等等)查找任何用户,但当涉及到安全性时,最重要的问题是“当前用户是谁?”
虽然任何主题都可以通过使用SecurityManager获得,但仅基于当前用户/主题的应用程序代码更加自然和直观。
当前正在执行的主体
在几乎所有的环境中,你都可以通过使用 org.apache.shiro.SecurityUtils
来获取当前正在执行的主题:
Subject currentUser = SecurityUtils.getSubject();
在独立的应用程序中,getSubject()调用可能会根据应用程序特定位置的用户数据返回一个主题,而在服务器环境(例如web应用程序)中,它会根据与当前线程或传入请求相关联的用户数据获取主题。
在你学习了现在的课程之后,你能做些什么呢?
如果你想让用户在他们当前的会话中使用这些东西,你可以得到他们的会话:
Session session = currentUser.getSession();
session.setAttribute( "someKey", "aValue" );
Session是一个特定于shiro的实例,它提供了常规httpsession所使用的大部分功能,但也有一些额外的好处和一个很大的区别:它不需要HTTP环境!
如果在web应用程序中部署,默认情况下会话将是基于HttpSession的。但是,
在一个非web环境中,比如这个简单的快速入门,Shiro默认情况下会自动使用它的企业会话管理。这意味着无论部署环境如何,您都可以在应用程序的任何层中使用相同的API。这打开了一个全新的应用程序世界,因为任何需要会话的应用程序都不需要强制使用HttpSession或EJB有状态会话bean。而且,任何客户机技术现在都可以共享会话数据。
所以现在你可以获得一个对象和他们的会话。那么真正有用的东西呢,比如检查它们是否被允许做一些事情,比如检查角色和权限?
登陆验证
我们只能对已知的用户做这些检查。上面的Subject实例表示当前用户,但是谁是当前用户呢?嗯,他们是匿名的——也就是说,直到他们至少登录一次。
那么,让我们这样做:
if ( !currentUser.isAuthenticated() ) {
//collect user principals and credentials in a gui specific manner
//such as username/password html form, X509 certificate, OpenID, etc.
//We'll use the username/password example here since it is the most common.
//(do you know what movie this is from? ;)
UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
//this is all you have to do to support 'remember me' (no config - built in!):
token.setRememberMe(true);
currentUser.login(token);
}
就是这样!再简单不过了。
但是,如果他们的登录尝试失败怎么办?你可以捕捉各种特定的异常,告诉你到底发生了什么:
try {
currentUser.login( token );
//if no exception, that's it, we're done!
} catch ( UnknownAccountException uae ) {
//username wasn't in the system, show them an error message?
} catch ( IncorrectCredentialsException ice ) {
//password didn't match, try again?
} catch ( LockedAccountException lae ) {
//account for that username is locked - can't login. Show them a message?
}
... more types exceptions to check if you want ...
} catch ( AuthenticationException ae ) {
//unexpected condition - error?
}
作为应用程序/GUI开发人员,您可以选择是否根据异常显示最终用户消息(例如,“系统中没有具有该用户名的帐户”)。
有许多不同类型的异常你可以检查,或者抛出你自己的Shiro可能无法解释的自定义条件。
更多信息请参阅AuthenticationException JavaDoc。
现在,我们有了一个登录用户。
权限校验
我们还能做什么?
让我们说说他们是谁:
//print their identifying principal (in this case, a username):
log.info( "User [" + currentUser.getPrincipal() + "] logged in successfully." );
我们也可以测试他们是否有特定的角色:
if ( currentUser.hasRole( "schwartz" ) ) {
log.info("May the Schwartz be with you!" );
} else {
log.info( "Hello, mere mortal." );
}
是否拥有权限:
if ( currentUser.isPermitted( "lightsaber:weild" ) ) {
log.info("You may use a lightsaber ring. Use it wisely.");
} else {
log.info("Sorry, lightsaber rings are for schwartz masters only.");
}
此外,我们还可以执行非常强大的实例级权限检查——查看用户是否有能力访问特定类型的实例的能力:
if ( currentUser.isPermitted( "winnebago:drive:eagle5" ) ) {
log.info("You are permitted to 'drive' the 'winnebago' with license plate (id) 'eagle5'. " +
"Here are the keys - have fun!");
} else {
log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
}
最后,登陆的用户也可以登出:文章来源:https://www.toymoban.com/news/detail-836844.html
currentUser.logout(); //removes all identifying information and invalidates their session too.
文章来源地址https://www.toymoban.com/news/detail-836844.html
到了这里,关于Shiro-14-subject 主体的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!