使用ini配置文件代表用户分组、密码、权限
slf4j+log4j日志输出
加载配置
public static void main(String[] args) {
log.info("My First Apache Shiro Application");
//1.
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//2.
SecurityManager securityManager = factory.getInstance();
//3.
SecurityUtils.setSecurityManager(securityManager);
System.exit(0);
}
使用shiro进行验证和授权访问
subject代表用户
官方描述:
a security-specific view of the currently executing user
更加广泛,并不一定指人也可以是第三方平台进程、定时任务、守护进程或任何类似的东西
It simply means ‘the thing that is currently interacting with the software’.
基本上在所有环境中都可以通过
Subject currentUser = SecurityUtils.getSubject();
来获取当前用户
getSubject会获取当前线程中保存的用户信息(是根据现成的threadlocal来获取的
page request session application
web应用中代表一次请求request(还是一次session?
it acquires the Subject
based on user data associated with current thread or incoming request.
多半是request
在程序运行时可获取当前用户与应用程序的会话 (session)无需在web环境中也可以获取(shiro的内置session?)
这里的Session代表shiro内置的,可以实现大部分HttpSession的功能并且有些额外的自己的功能
shiro自动识别不同环境,在web应用程序中使用基于HttpSession,在非web环境中提供shiro自己的企业级session管理器,可以在不同的应用中使用相同API
subject结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Svau2OhJ-1599285040726)(D:\Learning\shiro\Apache Shiro Tutorial.assets\image-20200829160102948.png)]
根据不同的subject环境获取session
获取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.
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);
}
通过丰富的验证示范exception
来支持您根据发生的不同情况进行处理做出反应
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?
}
// shiro登录
Subject currentUser = SecurityUtils.getSubject();
AuthToken token = new AuthToken(JSONObject.toJSONString(staffInfo));
String cSession;
try {
currentUser.login(token);
// 设置登录用户信息缓存
Session session = currentUser.getSession();
cSession = session.getId().toString();
} catch (UnknownAccountException e) {
throw new CheckResultException(ErrMsg.NO_ACCOUNT);
} catch (IncorrectCredentialsException e) {
throw new CheckResultException(ErrMsg.INVALID_ACCOUNT_PASS);
}
登录后调用自己实现的realm的逻辑去验证登录
NoPassRealm->doGetAuthenticationInfo
登录后可以进行角色验证和权限验证然后登出
//say who they are:
//print their identifying principal (in this case, a username):
log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
//test a role:
if (currentUser.hasRole("schwartz")) {
log.info("May the Schwartz be with you!");
} else {
log.info("Hello, mere mortal.");
}
//test a typed permission (not instance-level)
if (currentUser.isPermitted("lightsaber:wield")) {
log.info("You may use a lightsaber ring. Use it wisely.");
} else {
log.info("Sorry, lightsaber rings are for schwartz masters only.");
}
//a (very powerful) Instance Level permission:
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!");
}
//all done - log out!
currentUser.logout();
通过这个例子了解了如何在应用中使用shiro,shiro的主要设计意图,subject和securitymanager
这个应用很简单,如果不用INI而用复杂数据源(例如数据库)怎么办?
就需要接下去了解更深入的shiro架构以及配置机制。下一章
https://shiro.apache.org/architecture.html
Authentication是识别认证的过程,例如你将验证一位用户是否是他们自己所描述的那位用户。
为此,用户需要提供系统可以理解和信任的某种身份证明。
Shiro框架旨在使身份验证尽可能干净和直观,同时提供丰富的功能。
基于Subject(客体)
在shiro中所作的几乎所有操作都基于当前用户,称为一个课题。你能简单在任何代码找到Subject。这使得它更易于让你在应用中使用和理解shiro。
单一方法调用
验证过程是一个简单的单一的方法调用,只需要一个方法调用是的API和你的英语代码简洁节约时间更加高效
丰富的报错层次
shiro提供了一个丰富的报错层次结构来提供在登录失败时的报错异常。层次结构能帮你更加简单的诊断代码bug或客户关于登录验证服务的问题。另外如果需要丰富性还能帮你创建更复杂的验证方法。
记住我
shiro中的标准能够在你的用户返回应用的时候记住他们。你能以最小的工作量提供更好的用户体验。
可插拔的数据源
shori使用可插拔的数据访问对象(data access objects,DAOs),被称为Realms,来安全的链接数据源类似LDAP或者Active Diectory,JDBC。如果有需要你能创建自己的Realm来支持在基础Realm之外的特殊功能。
使用一个或多个数据源登录
使用Shiro,你能简单的验证一个用户违反一个或一些realms返回一个验证其身份的统一视图。另外你能使用shiro身份验证策略概念来定义自己的验证过程
Authorization(授权) ,也被称为访问控制,是一个应用程序中确定某个资源是否有访问权限的过程。换句话来说决定谁能访问它。授权用于回答类似是否用户能编辑账户、用户是否能访问网页,是否用户能点击这个按钮之类的安全问题。这些都是决定一个用户是否有权访问的检查。
Authorization授权是任何应用程序的关键要素,但它很快就会变得非常复杂。 Shiro的目标是消除授权方面的许多复杂性,以便您可以更轻松地构建安全软件。 下面是Shiro授权功能的重点。
原文 https://shiro.apache.org/tutorial.html