发表于: 2017-07-21 10:48:44

1 979


今天完成的:

收获:

1.Shiro

Apache Shiro是Java的一个安全框架,和spring security一样,但没有spring安全框架那么复杂,也是现在最流行的安全框架。

主要功能:

Authentication身份认证/登录,验证用户是不是拥有相应的身份;

Authorization授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;

Session Manager会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;

Cryptography加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;

Web SupportWeb支持,可以非常容易的集成到Web环境;

Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;

Concurrencyshiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;

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()设置;

2SecurityManager负责真正的身份验证逻辑;它会委托给Authenticator进行身份验证;

3Authenticator才是真正的身份验证者,Shiro API中核心的身份认证入口点,此处可以自定义插入自己的实现;

4Authenticator可能会委托给相应的AuthenticationStrategy进行多Realm身份验证,默认ModularRealmAuthenticator会调用AuthenticationStrategy进行多Realm身份验证;

5Authenticator会把相应的token传入Realm,从Realm获取身份验证信息,如果没有返回/抛出异常表示身份验证失败了。此处可以配置多个Realm,将按照相应的顺序及策略进行访问。

doGetAuthorizationInfo执行时机有三个,如下:

1subject.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

  1. <shiro:hasRole name="admin">  
  2. <!— 有权限 —>  
  3. </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只是提供相应的#接口方便验证.

#基于资源的访问控制(显示角色)

  1. [users]  
  2. zhang=321,role1,role2  
  3. wang=321,role1  
  1. [roles]  
  2. role1=user:create,user:update  
  3. 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


返回列表 返回列表
评论

    分享到