发表于: 2017-07-21 10:48:44
1 979
今天完成的:
收获:
1.Shiro
Apache Shiro是Java的一个安全框架,和spring security一样,但没有spring安全框架那么复杂,也是现在最流行的安全框架。
主要功能:
Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;
Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
Web Support:Web支持,可以非常容易的集成到Web环境;
Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;
Concurrency:shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
Testing:提供测试支持;
Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。
控制同一个用户的在线数量。(挤出之前的登录用户)
Shiro 登录后跳转到最后一个访问的页面
在线显示,在线用户管理(踢出登录)。
登录注册密码加密传输。
集成动态验证码。
Shiro不会去维护用户、维护权限;这些需要我们自己去设计/提供;然后通过相应的接口注入给Shiro即可。
一些shiro专有名词:
Subject:与当前应用交互的任何东西都是Subject
SecurityManager:安全管理器;即所有与安全有关的操作都会与SecurityManager交互,类似springMVC的前端控制器
Realm:域,Shiro从从Realm获取安全数据,类似数据源或者管理用户验证的dao层。shiro提供了多种方式访问数据源,如jdbc,xml,ini甚至json
Authenticator:认证器,负责主体认证的,这是一个扩展点,如果用户觉得Shiro默认的不好,可以自定义实现;其需要认证策略(Authentication Strategy),即什么情况下算用户认证通过了;
Authrizer:授权器,或者访问控制器,用来决定主体是否有权限进行相应的操作;即控制着用户能访问应用中的哪些功能
用户登录验证流程:
1、首先调用Subject.login(token)进行登录,其会自动委托给Security Manager,调用之前必须通过SecurityUtils. setSecurityManager()设置;
2、SecurityManager负责真正的身份验证逻辑;它会委托给Authenticator进行身份验证;
3、Authenticator才是真正的身份验证者,Shiro API中核心的身份认证入口点,此处可以自定义插入自己的实现;
4、Authenticator可能会委托给相应的AuthenticationStrategy进行多Realm身份验证,默认ModularRealmAuthenticator会调用AuthenticationStrategy进行多Realm身份验证;
5、Authenticator会把相应的token传入Realm,从Realm获取身份验证信息,如果没有返回/抛出异常表示身份验证失败了。此处可以配置多个Realm,将按照相应的顺序及策略进行访问。
doGetAuthorizationInfo执行时机有三个,如下:
1、subject.hasRole(“admin”) 或 subject.isPermitted(“admin”):自己去调用这个是否有什么角色或者是否有什么权限的时候;
2、@RequiresRoles("admin") :在方法上加注解的时候;
3、[@shiro.hasPermission name = "admin"][/@shiro.hasPermission]:在页面上加shiro标签的时候,即进这个页面的时候扫描到有这个标签的时候。
三种授权方式:
1.通过java代码subject.hasRole(“admin”)
2.通过注解@RequiresRoles("admin")
3.通过jsp TAG
- <shiro:hasRole name="admin">
- <!— 有权限 —>
- </shiro:hasRole>
测试类
@Test
public void testHelloworld() {
/* 1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager,实际应使用DB。
ini配置方式将使用org.apache.shiro.realm.text.IniRealm。实际应该自己写realm类 */
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//2、得到SecurityManager实例 并绑定给SecurityUtils
org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
//3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证),模拟用户输入的。
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
try {
//4、登录,即身份验证
subject.login(token);logger.debug("login success!");
} catch (AuthenticationException e) {
//5、身份验证失败
}
Assert.assertEquals(true, subject.isAuthenticated()); //断言用户已经登录
//6、退出
// subject.logout();//subject().isPermitted("user:view")判断该subject是否拥有该权限
boolean isHasRole = subject.hasRole("role1");
System.out.println("正确角色,角色有权限--->" + isHasRole);
//传入错误的角色
boolean isHasRole2 = subject.hasRole("role12");
System.out.println("错误角色,角色有权限--->" + isHasRole2);
//判断多个角色
boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("role1", "role2"));
System.out.println("多个角色判断--->" + hasAllRoles);
}
ini数据源
#基于角色的访问控制(隐式角色)
#用户
[users]
zhang=123,role1,role2
wang=123,role2
#规则即:“用户名=密码,角色1,角色2”,#权限.Shiro不负责维护用户-角色信息,需要应用提供,Shiro只是提供相应的#接口方便验证.#基于资源的访问控制(显示角色)
- [users]
- zhang=321,role1,role2
- wang=321,role1
- [roles]
- role1=user:create,user:update
- role2=user:create,user:delete
#规则:“用户名=密码,角色1,角色2”“角色=权限1,权限2”,即首先根据用户名找到角色,然后根据角色再找到权 #限;即角色是权限集合;Shiro同样不进行权限的维护,需要我们通过Realm返回相应的权限信息。只需要维护“用 #户——角色”之间的关系即可。用户与角色是一对多,角色与权限是一对多
遇到的问题:
1.写测试的时候遇到了jar包冲突,原因是shiro包里依赖的slf4j和项目中log4j不兼容导致。
解决:找了一个兼容版本,根据maven依赖路径最短优先,将下面的slf4j覆盖后删除。
2.路径跳转没有项目名
一般是idea的tomcat项目名没设置,然而并没有。一看jsp,竟然是路径忘了写全。。。
<form id="" action="<%=request.getContextPath()%>/shirotest/dologin" method="post">
明天的计划:
希望明天能把Task4的项目用shiro整合起来,包括session和cookie
评论