【易学day07】shiro安全框架

SSM

Commons-fileupload

Poi:   

     搜索"导出excel java"

     能够完成excel读写,jxl和poi

     一般情况下,读至少3个网站或博客,对比那种实现方案更合适

     jxl读写速度优于poi,但是,不能对office 2007以后的版本进行读写

    只能选择poi

   搜做poi java 找到poi的官方网站

          1.下载jar包

          2.寻找实现方案或代码,构建简单demo

          3.跑通demo后再去寻找更复杂实现

          4.去博客或专业网站csdn,iteye,cnblog,51cto…等

 

做excel的步骤:

   导入jar包

    手工:

   maven:

          <!-- 微软的office组件 excel --> 

      <dependency>

      <groupId>org.apache.poi</groupId>

      <artifactId>poi</artifactId>

      <version>3.13</version>

      </dependency>

   根据需求写好导出到excel的工具类

   通过response对象,把excel文件下载

        @RequestMapping(value="/exportuser",method=RequestMethod.GET)

     public void exportUser(HttpServletRequest request,

                         HttpServletResponse response){

                Result result=null;

               try {

                byte[] data=this.userService.exportUser();

                //下载data数组为excel文件

     response.setContentType("application/x-msdownload");

    response.setHeader("Content-Disposition", "attachment;fileName=alluser.xls");

    response.setContentLength(data.length);

    OutputStream os=response.getOutputStream();

    os.write(data);

    os.flush();

    os.close();

              } catch (IOException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

              }

 

          }

 

shiro安全框架

       类似的产品:spring secrety  学习成本高,过于复杂

       shiro相对简单一些

       spring mvc 拦截器 也可以做到安全管理

  安全的目标:

      访问web资源的时候,没有正常登陆,是不能访问项目的任何的敏感资源

 

shiro框架都能做什么:

   主要的:

       登陆认证:

              通过shiro做登陆操作,如果没登陆成功,就跳转到登录页面

                  如果登录成功,就跳转指定主页,而且还可以访问其他任何资源

                  其实,只有通过shiro认证的登录,才可以正常访问项目资源

         授权认证:

                  根据不同用户的权限,登录的时候显示不同主页菜单

 

shiro的全模块功能:

 

 

Primary:

   Autentication:登录认证

   Authorization:授权认证

   Session Management :session 管理

   Cryptographt:加密管理

Supporting:

  web support:shiro支持web项目

  caching:在shiro可以做部分数据缓存管理

  testing /run as:shiro支持java项目

 

shoiro工作流程图:

 

 

 

  appliction code:应用程序的代码,最终对应一个方法,此方法中启动shiro

 subject(主题,科目)/user:shiro框架可以创建很多个subject,每个subject

                                      可以看成一个用户在操作一个主题

  shiro securityManager:shiro的安全管理器,是shiro的核心,可以管理所有

                                                 主题,所有安全认证,都是此安全管理器中认证

  realm(领域,范围):shiro的领域是数据库中的数据tesdb    t_user

 

 

简单介绍shiro的登录认证流程:

     用户名和密码是用户在页面输入的,通过shiro的api启动shiro,把页面的

      用户名的密码存储subject,再把subject传递给shiro securityManager,

    shiro securityManager,负责调用realm(获取数据源的数据),把数据返回

      给安全中心,

     此时的安全中心有用户的subject 还有realm,安全中心负责对subject和

     realm中的数据做对比,如果对比成功就跳转到指定页面,然后本项目其余

     所有 的资源都可以访问

  

对于所有请求,都要经过shiro来判断是否是登录用户,过滤器只是负责拦截请求

所以在shiro的web项目中的web.xml中要添加过滤器

通过拦截进入shiro,在执行某个方法的时候,"得提前检测是否是登录用户"

 

shiro的底层用到了动态代理

    //环绕通知

   public Object around(ProceedJoinPoint pjp){

          Object returnObj=null;

        try{

       //前置通知

       if(登录过){

              returnObj=pjp.proceed();

       }else{

        //跳转到指定的登录页面上,

        //登录页面是从spring_shiro.xml中获取

       }

     //后置通知

        }catch(Exception e){

                    //异常通知

                }finally{

                    // 最终通知

                  }

        

    }

 

shiro的使用步骤:

 导入shiro的jar包

   手工:

  maven:    

                    <!-- Apache Shiro 权限依赖 -->

<dependency>

<groupId>org.apache.shiro</groupId>

<artifactId>shiro-all</artifactId>

<version>1.2.3</version>

</dependency>

<!-- spring aop 依赖 -->

<dependency>

  <groupId>org.springframework</groupId>

  <artifactId>spring-aop</artifactId>

  <version>4.3.7.RELEASE</version>

</dependency>

 

<dependency>

  <groupId>org.aspectj</groupId>

  <artifactId>aspectjweaver</artifactId>

  <version>1.8.7</version>

</dependency>

    shirio的配置文件:

      web.xml:shiro的入口

 

 

 

     spring_shiro.xml:shiro的所有的对象要给spring容器

<!--将Shiro的组件以bean的形式交给Spring管理  -->

 <bean id="lifeCycleBeanProcessor"

 class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean>

 

<!--Spring为shiro的bean创建代理对象 

代理的方式:

1.jdk

2.cglib

 -->

 <bean

 class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"

 depends-on="lifeCycleBeanProcessor">

         <!--表示强制使用cglib为其创建代理对象  -->

         <property name="proxyTargetClass" value="true"></property>

 </bean>

 

 

<!--切面中需要的对象,也使用cglib来创建代理对象  -->

<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>

          

          

          <!--Shiro的安全中心  其中需要提供真实的用户信息. 需要加载realm  -->

 <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">

         

         <property name="realm" ref="AuthRealm"></property>

 </bean>

 

 <!--自定义Realm 为安全中心提供信息  -->

 <bean id="AuthRealm" class="com.tarena.shiro.AuthRealm">

         <property name="credentialsMatcher" ref="authCredential"></property>

 </bean>

 

 

 <!--自定义加密算法  -->

 <bean id="authCredential" class="com.tarena.shiro.AuthCredential"/>

 

 

 <!--授权,权限认证的适配器  -->

 <bean  class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">

         <property name="securityManager" ref="securityManager"></property>

 </bean>

 

 <!-- shiro的过滤器  -->

 <bean id="shiroFilter"  class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

         <!--配置安全中心  -->

         <property name="securityManager" ref="securityManager"></property>

         

         <!--指定登陆的地址  当用户没有登陆时.默认跳转该页面-->

         <property name="loginUrl" value="/login.html"></property>

         

         <!--过滤器链  -->

         <property name="filterChainDefinitions">

         <value>

                 <!--添加过滤信息

                         1.anon  表示放行

                         2.authc 表示拦截-->

         /user/login = anon

         /css/**  = anon

         /font-awesome/**  = anon

         /fonts/**  = anon

         /head/**  = anon

         /images/**  = anon

         /js/**  = anon

         /page/**  = anon

         <!--/** 拦截所有的请求和静态资源文件  -->

        /index.html* = authc

        /index.jsp* = authc

         /** = authc

         </value>

         </property>

 </bean>

 

创建两个java类

     处理登录认证和授权认证的类

  public class AuthRealm extends AuthorizingRealm{

@Resource

private UserMapper userMapper;

//授权认证的回调方法

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

//得到用户对象

Subject subject = SecurityUtils.getSubject();

String username = subject.getSession().getAttribute("username").toString();

//根据用户名查询模块信息 (获取模块名的集合)

List<String> moduleList = userMapper.findModuleByUserName(username);

 

//创建授权管理

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

 

//传入授权管理的集合信息

info.addStringPermissions(moduleList);

return info;

}

 

@Override

//登陆认证模块的回调方法

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

UsernamePasswordToken loginToken =  (UsernamePasswordToken) token;

String username = loginToken.getUsername();

//User user = userMapper.findUserByUserName(username);

/*

 * principal:主要的; 本金的; 最重要的; 资本的; 真实的对象

 * credentials:凭证,证件; 表示真实的密码

 * realmName: 域,范围的名字 当前的realm

 */

//AuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),this.getName());

return null;

 

}

}

 

 

    加密算法类   

public class AuthCredential extends  SimpleCredentialsMatcher{

 

@Override

public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {

//通过token 获取用户名和密码

UsernamePasswordToken userToken = (UsernamePasswordToken) token;

/*String username = userToken.getUsername();

String password = String.valueOf(userToken.getPassword());

 

String encryptPassword = Encrypt.getMd5(password, username);

userToken.setPassword(encryptPassword.toCharArray());*/

 

return super.doCredentialsMatch(userToken, info);

}

}

//这是用来执行加密的工具类

public class Encrypt {

 

public static String getMd5(String password,String username){

 

return new Md5Hash(password, username, 3).toString();

}

 

public static void main(String[] args) {

String password = new Md5Hash("admin", "admin", 3).toString();

System.out.println(password);

}

}

 

 

做完shiro登录后用shiro和不用shiro的区别:

    不用shiro:

         select user_id form t_user

         where user_loginname=#{} and

                    user_password=#{}

   用shiro:

         select user_id   id,

                   user_loginname loginName,

                   user_password password   

         from t_user

         where  user_loginname=#{}

   不用shiro:

      优点:访问数据库一次,能够完成登录业务

      缺点:不能防护所有的敏感资源

  用shiro:     

优点:访问数据库一次,能够完成登录业务,可以防护敏感资源

      缺点:性能堪忧,因为每访问任何一个资源,都要经过shiro的判断,

              是否是登录用户

 

7008     wt_zss@126.com   角色管理,用户管理,课程管理,活动管理

A28   admin@tedu.cn  角色管理,用户管理,课程管理,视频管理,

                                                  活动管理,评论管理

根据不同的账号名,登录成功后,显示的模块多少不通

 

 

 

posted @ 2018-06-06 22:04  songyao  阅读(68)  评论(0)    收藏  举报