发表于: 2017-07-10 22:51:46

1 1185


今天完成的事情:讲小课堂,学习shiro框架

什么是shiro?

Apache Shiro是一个功能强大、灵活的,开源的安全框架。它可以干净利落地处理身份验证、授权、企业会话管理和加密。

Apache Shiro的首要目标是易于使用和理解。安全通常很复杂,甚至让人感到很痛苦,但是Shiro却不是这样子的。一个好的安全框架应该屏蔽复杂性,向外暴露简单、直观的API,来简化开发人员实现应用程序安全所花费的时间和精力。


Shiro能做什么呢?

验证用户身份

用户访问权限控制,比如:1、判断用户是否分配了一定的安全角色。2、判断用户是否被授予完成某个操作的权限

在非 web 或 EJB 容器的环境下可以任意使用Session API

可以响应认证、访问控制,或者 Session 生命周期中发生的事件

可将一个或以上用户安全数据源数据组合成一个复合的用户 “view”(视图)

支持单点登录(SSO)功能

支持提供“Remember Me”服务,获取用户关联信息而无需登录


Apache Shiro Features特性

Apache Shiro是一个全面的、蕴含丰富功能的安全框架。下图为描述Shiro功能的框架图:



Authentication(认证), Authorization(授权), Session Management(会话管理), Cryptography(加密)被 Shiro 框架的开发团队称之为应用安全的四大基石。那么就让我们来看看它们吧:

Authentication(认证):用户身份识别,通常被称为用户“登录”

Authorization(授权):访问控制。比如某个用户是否具有某个操作的使用权限。

Session Management(会话管理):特定于用户的会话管理,甚至在非web 或 EJB 应用程序。

Cryptography(加密):在对数据源使用加密算法加密的同时,保证易于使用。


还有其他的功能来支持和加强这些不同应用环境下安全领域的关注点。特别是对以下的功能支持:

Web支持:Shiro 提供的 web 支持 api ,可以很轻松的保护 web 应用程序的安全。

缓存:缓存是 Apache Shiro 保证安全操作快速、高效的重要手段。

并发:Apache Shiro 支持多线程应用程序的并发特性。

测试:支持单元测试和集成测试,确保代码和预想的一样安全。

“Run As”:这个功能允许用户假设另一个用户的身份(在许可的前提下)。

“Remember Me”:跨 session 记录用户的身份,只有在强制需要时才需要登录。

注意: Shiro不会去维护用户、维护权限,这些需要我们自己去设计/提供,然后通过相应的接口注入给Shiro


高级概述

在概念层,Shiro 架构包含三个主要的理念:Subject,SecurityManager和 Realm。下面的图展示了这些组件如何相互作用,我们将在下面依次对其进行描述。



Subject:当前用户,Subject 可以是一个人,但也可以是第三方服务、守护进程帐户、时钟守护任务或者其它–当前和软件交互的任何事件。

SecurityManager:管理所有Subject,SecurityManager 是 Shiro 架构的核心,配合内部安全组件共同组成安全伞。

Realms:用于进行权限信息的验证,我们自己实现。Realm 本质上是一个特定的安全 DAO:它封装与数据源连接的细节,得到Shiro 所需的相关的数据。在配置 Shiro 的时候,你必须指定至少一个Realm 来实现认证(authentication)和/或授权(authorization)。

我们需要实现Realms的Authentication 和 Authorization。其中 Authentication 是用来验证用户身份,Authorization 是授权访问控制,用于对用户进行的操作授权,证明该用户是否允许进行当前操作,如访问某个链接,某个资源文件等。


登录实现

@RequestMapping("/login")
public String login(HttpServletRequest request, Map<String, Object> map) throws Exception{
System.out.println("HomeController.login()");
  // 登录失败从request中获取shiro处理的异常信息。
  // shiroLoginFailure:就是shiro异常类的全类名.
  String exception = (String) request.getAttribute("shiroLoginFailure");
  System.out.println("exception=" + exception);
  String msg = "";
  if (exception != null) {
if (UnknownAccountException.class.getName().equals(exception)) {
System.out.println("UnknownAccountException -- > 账号不存在:");
        msg = "UnknownAccountException -- > 账号不存在:";
     } else if (IncorrectCredentialsException.class.getName().equals(exception)) {
System.out.println("IncorrectCredentialsException -- > 密码不正确:");
        msg = "IncorrectCredentialsException -- > 密码不正确:";
     } else if ("kaptchaValidateFailed".equals(exception)) {
System.out.println("kaptchaValidateFailed -- > 验证码错误");
        msg = "kaptchaValidateFailed -- > 验证码错误";
     } else {
msg = "else >> "+exception;
        System.out.println("else -- >" + exception);
     }
}
map.put("msg", msg);
  // 此方法不处理登录成功,由shiro进行处理
  return "/login";
}

ShiroConfig

@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
System.out.println("ShiroConfiguration.shirFilter()");
     ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
     shiroFilterFactoryBean.setSecurityManager(securityManager);
     //拦截器.
     Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
     // 配置不会被拦截的链接 顺序判断
     filterChainDefinitionMap.put("/static/**", "anon");
     //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
     filterChainDefinitionMap.put("/logout", "logout");
     //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
     //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
     filterChainDefinitionMap.put("/**", "authc");
     // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
     shiroFilterFactoryBean.setLoginUrl("/login");
     // 登录成功后要跳转的链接
     shiroFilterFactoryBean.setSuccessUrl("/index");

     //未授权界面;
     shiroFilterFactoryBean.setUnauthorizedUrl("/403");
     shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
     return shiroFilterFactoryBean;
  }

@Bean
public MyShiroRealm myShiroRealm(){
MyShiroRealm myShiroRealm = new MyShiroRealm();
     return myShiroRealm;
  }


@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
     securityManager.setRealm(myShiroRealm());
     return securityManager;
  }
}

明天计划的事情:继续完成shiro编译

遇到的问题:没写完,还没开始跑等跑了再说

收获:学习shiro


返回列表 返回列表
评论

    分享到