Shiro使用详解

Shiro

1.权限管理的概念

基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源。

权限管理包括用户身份认证和授权两部分,简称认证授权。对于需要访问控制的资源用户首先经过身份认证,认证通过后用户具有该资源的访问权限方可访问。

2.认证

1.认证的概念

  • 认证:用户访问系统的控制

2.认证中抽象出的对象

  • subject :主体相当于之前的user,访问系统的用户,主体可以是用户、程序等,进行认证的都称为主体;
  • Principal:身份信息,是主体(subject)进行身份认证的标识,标识必须具有唯一性,如用户名、手机号、邮箱地址等,一个主体可以有多个身份,但是必须有一个主身份(Primary Principal)。
  • credential:凭证信息,是只有主体自己知道的安全信息,如密码、证书等.

3.授权

1.授权的概念

  • 授权,即访问控制,控制谁能访问哪些资源。主体进行身份认证后需要分配权限方可访问系统的资源,对于某些资源没有权限是无法访问的。

2.授权中抽象对象

  • Who,即主体(Subject),主体需要访问系统中的资源。
  • What,即资源(Resource),如系统菜单、页面、按钮、类方法、系统商品信息等。资源包括资源类型和资源实例,比如商品信息为资源类型,类型为t01的商品为资源实例,编号为001的商品信息也属于资源实例。
  • How,权限/许可(Permission),规定了主体对资源的操作许可,权限离开资源没有意义,如用户查询权限、用户添加权限、某个类方法的调用权限、编号为001用户的修改权限等,通过权限可知主体对哪些资源都有哪些操作许可。权限分为粗颗粒和细颗粒,粗颗粒权限是指对资源类型的权限,细颗粒权限是对资源实例的权限。

4.权限模型

5.权限控制的方案

1.基于角色的权限控制

RBAC基于角色的访问控制(Role-Based Access Control)是以角色为中心进行访问控制,比如:主体的角色为总经理可以查询企业运营报表,查询员工工资信息等,访问控制流程如下:

if(主体.hasRole(“总经理角色id”)){

查询工资

}

2.基于资源的权限控制

RBAC基于资源的访问控制(Resource-Based Access Control)是以资源为中心进行访问控制,比如:主体必须具有查询工资权限才可以查询员工工资信息等,访问控制流程如下:

if(主体.hasRole(“查询工资的权限”)){

查询工资

}

6.什么是shiro

Shiro是apache旗下一个开源框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权、加密、会话管理等功能,组成了一个通用的安全认证框架.

7.为什么要学shiro

既然shiro将安全认证相关的功能抽取出来组成一个框架,使用shiro就可以非常快速的完成认证、授权等功能的开发,降低系统成本。shiro使用广泛,shiro可以运行在web应用,非web应用,集群分布式应用中越来越多的用户开始使用shiro。java领域中spring security(原名Acegi)也是一个开源的权限管理框架,但是spring security依赖spring运行,而shiro就相对独立,最主要是因为shiro使用简单、灵活,所以现在越来越多的用户选择shiro。

8.shiro的核心架构图

9.shiro的第一个程序

1.创建一个maven或者springboot项目

2.导入jar

<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-core</artifactId>
  <version>1.3.2</version>
</dependency>

2.第一个认证的程序

package com.baizhi.test;


import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;

public class TestShiro {

    public static void main(String[] args) {

        //获取安全管理器工厂
        IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro.ini");

        //通过工厂 获取安全管理器
        SecurityManager securityManager = iniSecurityManagerFactory.getInstance();

        //将安全管理器 给 安全工具类
        SecurityUtils.setSecurityManager(securityManager);

        //获取主体对象
        Subject subject = SecurityUtils.getSubject();

        //token   就是用户的令牌  包含用户的身份信息和凭证信息
        AuthenticationToken token =new UsernamePasswordToken("zhangcn","111111");

        try {
            //认证
            subject.login(token);
        } catch (AuthenticationException e) {
            e.printStackTrace();
            // AuthenticationToken   未找到账户异常
            // IncorrectCredentialsException   证书不正确异常
        }

        //当前用户是否通过验证
        boolean authenticated = subject.isAuthenticated();
        System.out.println(authenticated);
    }

}

3.配置文件

shiro.ini

[users]
zhangcn=111111
lisi=123456

注意:shiro中主体是否认证成功是通过抛异常的形式体现的,一般会抛出两个异常

  • UnknownAccountException 未找到账户异常 账号异常
  • IncorrectCredentialsException 证书不正确异常 密码异常

10.shiro认证连接数据库

1.源码追踪中出现的关键对象

AuthenticatingRealm  //抽象类
    //3.关键属性 该属性为凭证匹配器
    CredentialsMatcher credentialsMatcher;
    //1.该方法为抽象方法 其作用使用来获取数据
    protected abstract AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken var1) throws AuthenticationException;


SimpleAccountRealm
//2.实现了AuthenticatingRealm抽象方法,用来获取配置文件中的用户信息,该类不做数据比对

SimpleCredentialsMatcher
//4.shiro中默认的凭证匹配器
  public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        Object tokenCredentials = this.getCredentials(token);
        Object accountCredentials = this.getCredentials(info);
        return this.equals(tokenCredentials, accountCredentials);
    }

2.连接数据库

1.开发自定义realm

package com.baizhi.test;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.AuthenticatingRealm;

public class MyRealm extends AuthenticatingRealm {

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        //根据token 获取身份信息
        String username = (String) authenticationToken.getPrincipal();
        //调用根据用户名查询用户的方法  数据库操作
        //User user=userDao.queryByName(username);
        AuthenticationInfo authenticationInfo=null;
        if(username.equals("zhangcn")){
            authenticationInfo = new SimpleAuthenticationInfo("zhangcn","111111",this.getName());
        }
        return authenticationInfo;
    }
}

2.告知shiro要使用自定义realm

[main]

#自定义 realm
customRealm=com.baizhi.test.MyRealm

#将realm设置到securityManager
securityManager.realms=$customRealm

注意:需要导入一个jar

<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>

11.shiro的加密认证方式

1.加密测试

@Test

public void testMD5() {
        //参数  明文密码
    	Md5Hash md5Hash = new Md5Hash("111111");
        //参数  明文密码 盐值
        Md5Hash md5Hash = new Md5Hash("111111","ABCD");
    	//参数  明文密码 盐值 散列次数
        Md5Hash md5Hash = new Md5Hash("111111","ABCD",1024);
    	//调用加密方法
        String s = md5Hash.toHex();
        System.out.println(s);
}

2.realm返回密文数据

package com.baizhi.test;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.util.ByteSource;

public class MyRealm extends AuthenticatingRealm {

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        //根据token 获取身份信息
        String username = (String) authenticationToken.getPrincipal();
        //调用根据用户名查询用户的方法
        //User user=userDao.queryByName(username);
        AuthenticationInfo authenticationInfo=null;
        if(username.equals("zhangcn")){
            //参数: 数据库取出的 用户名 密文  盐值
            authenticationInfo = new SimpleAuthenticationInfo("zhangcn","e0504e77b06f5a26faf37d044c65992b", ByteSource.Util.bytes("ABCD"),this.getName());
        }
        return authenticationInfo;
    }
}

3.修改配置文件,加入凭证匹配器的相关配置

[main]

#自定义凭证匹配器
hashedCredentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher

#自定义 realm
customRealm=com.baizhi.test.MyRealm

#凭证匹配器告诉谁
customRealm.credentialsMatcher=$hashedCredentialsMatcher
hashedCredentialsMatcher.hashAlgorithmName=MD5
hashedCredentialsMatcher.hashIterations=1024

#将realm设置到securityManager
securityManager.realms=$customRealm

12.授权

1.授权数据来源于数据库

public class MyRealm extends AuthorizingRealm {
    //获取数据  获取认证的数据
    protected  AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token){
        //数据库操作   基于身份信息查主体
        
    }

     //获取数据  获取授权的数据
    protected  AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection var1){
         //数据库操作   基于身份信息查主体   基于主体查角色    基于角色查权限
       
    }
    
}

1-1.示例

package com.baizhi.test;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.Arrays;
import java.util.List;

public class MyRealm extends AuthorizingRealm {

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        //根据token 获取身份信息
        String username = (String) authenticationToken.getPrincipal();
        //调用根据用户名查询用户的方法
        //User user=userDao.queryByName(username);
        AuthenticationInfo authenticationInfo=null;
        if(username.equals("zhangcn")){
            //参数  用户名,密码,盐值,类名
            authenticationInfo = new SimpleAuthenticationInfo("zhangcn","e0504e77b06f5a26faf37d044c65992b", ByteSource.Util.bytes("ABCD"),this.getName());
        }

        return authenticationInfo;
    }

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        //主体  角色  权限
        //从数据库查   主身份
        String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
        if(primaryPrincipal.equals("zhangcn")){

            //从数据库查根据主体查角色
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            //添加角色
            simpleAuthorizationInfo.addRole("super");
            //simpleAuthorizationInfo.addRole("admin");
            //添加权限
            //simpleAuthorizationInfo.addStringPermission("admin:delete");
            //添加多个权限
            List<String> strings = Arrays.asList("admin:delete","admin:query","admin:update");
            simpleAuthorizationInfo.addStringPermissions(strings);
            return simpleAuthorizationInfo;
        }

        return null;
    }
}

2.java环境下授权的api

  • 基于角色
    //判断当前主体是否包含此角色
    boolean b = subject.hasRole(“super”);

    			//判断当前主体是否包含某个角色
                List<String> list = Arrays.asList("super", "admin");
                boolean[] booleans = subject.hasRoles(list);
    
                //判断当前主体是否包含全部角色
                boolean b = subject.hasAllRoles(list);
    
  • 基于资源
    //判断当前角色是否包含此权限
    boolean permitted = subject.isPermitted(“admin:delete”);

                 //判断当前角色是否包含某个权限
                String[] str={"admin:delete","admin:insert"};
                boolean[] permitted = subject.isPermitted(str);
    
                //判断当前角色是否包含全部权限
                boolean permittedAll = subject.isPermittedAll(str);
    

2-1示例

package com.baizhi.test;


import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.A                                                                                                                                                  uthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;

import java.util.Arrays;
import java.util.List;

public class TestShiro {

    public static void main(String[] args) {

        //获取安全管理器工厂
        IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory();

        //通过工厂 获取安全管理器
        SecurityManager securityManager = iniSecurityManagerFactory.getInstance();

        //将安全管理器 给 安全工具类
        SecurityUtils.setSecurityManager(securityManager);

        //获取主体对象
        Subject subject = SecurityUtils.getSubject();

        //token   就是用户的令牌  包含用户的身份信息和凭证信息
        AuthenticationToken token =new UsernamePasswordToken("zhangcn","111111");

        try {
            //认证
            subject.login(token);
        } catch (AuthenticationException e) {
            e.printStackTrace();
            // AuthenticationToken   未找到账户异常
            // IncorrectCredentialsException   证书不正确异常
        }

        //当前用户是否通过验证 是否认证通过
        boolean authenticated = subject.isAuthenticated();
        //基于角色
        if(authenticated){
            //  admin super

            if(subject.hasRole("super")){
                System.out.println("super");
            }
            //判断当前主体是否包含此角色
            //boolean b = subject.hasRole("super");
            List<String> str = Arrays.asList("super", "admin");
            //判断当前主体是否包含某个角色
            boolean[] booleans = subject.hasRoles(str);
            for (int i = 0; i < booleans.length; i++) {
                boolean aBoolean = booleans[i];
                System.out.println(aBoolean);
            }

            //判断当前主体是否包含全部的角色
            boolean b = subject.hasAllRoles(str);
            System.out.println(b);
        }*/
        //基于资源
        if(authenticated){
            //判断当前角色是否包含此权限
            boolean permitt = subject.isPermitted("admin:delete");
            //如果包含此权限   继续执行操作
            if(permitted){
                //adminDao.delete(id);  执行删除方法
                System.out.println("执行删除方法");
            }

            //判断当前角色是否包含某个权限
            String[] str={"admin:delete","admin:insert"};
            boolean[] permitted = subject.isPermitted(str);
            for (int i = 0; i < permitted.length; i++) {
                boolean b = permitted[i];
                System.out.println(b);
            }

            //判断当前角色是否包含全部权限
            boolean permittedAll = subject.isPermittedAll(str);
            System.out.println(permittedAll);
        }
    }

}

3.权限的标识符

权限字符串的规则是:“资源标识符:操作:资源实例标识符”,意思是对哪个资源的哪个实例具有什么操作,“:”是资源/操作/实例的分割符,权限字符串也可以使用*通配符。

例子:

  • 用户创建权限:user:create,或user:create:*
  • 用户修改实例001的权限:user:update:001
  • 用户实例001的所有权限:user:*:001

13.springboot环境下的认证和授权

1.相关的jar

<!-- 给内嵌tomcat提供jsp解析功能的jar-->
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
</dependency>

<dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
<!--shiro相关jar包-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.3.2</version>
</dependency>

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-web</artifactId>
    <version>1.3.2</version>
</dependency>

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-ehcache</artifactId>
    <version>1.3.2</version>
</dependency>

<!--shiro与spring整合相关jar包-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.3.2</version>
</dependency>

2.配置shrio的核心过滤器

@Configuration
public class ShiroFilterConf {
    //shiro过滤器的配置
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //多个过滤器  AnonymousFilter  匿名过滤器   anon 
        // FormAuthenticationFilter 认证过滤器 authc
        Map<String, String> map = new HashMap<>();
        map.put("/user/loginUser", "anon");
        map.put("/index.jsp", "anon");
        map.put("/**", "authc");
        //设置登录入口的路径
        shiroFilterFactoryBean.setLoginUrl("/main/login.jsp");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }
   //shiro的核心对象 安全管理器
    @Bean
    public SecurityManager getSecurityManager(Realm realm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(realm);
        return securityManager;
    }
    //自定义realm
    @Bean
    public Realm getRealm(CredentialsMatcher credentialsMatcher) {
        MyRealm myRealm = new MyRealm();
        myRealm.setCredentialsMatcher(credentialsMatcher);
        return myRealm;
    }
   //选择HashedCredentialsMatcher 凭证匹配器
    @Bean
    public CredentialsMatcher getCredentialsMatcher() {
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        hashedCredentialsMatcher.setHashIterations(1024);
        return hashedCredentialsMatcher;
    }

}

//缓存jar包

<!--缓存jar包-->
<dependency>
    <groupId>org.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>3.6.3</version>
</dependency>

3.shiro过滤器

ssl :org.apache.shiro.web.filter.authz.SslFilter
user :org.apache.shiro.web.filter.authz.UserFilter
anon :org.apache.shiro.web.filter.authc.AnonymousFilter
port :org.apache.shiro.web.filter.authz.PortFilter
rest :org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
authc :org.apache.shiro.web.filter.authc.FormAuthenticationFilter
perms :org.apache.shiro.web.filter.authz.PermissionAuthorizationFilter
roles :org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
logout :org.apache.shiro.web.filter.authc.LogoutFilter
authcBasic :org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
noSessionCreation :org.apache.shiro.web.filter.session.NoSessionCreationFilter

过滤器简称
过滤器 作用

4.shiro中相关的标签

<shiro:principal></shiro:principal>  //用户的身份信息
<shiro:authenticated></shiro:authenticated> //认证成功  执行标签体的内容
<shiro:notAuthenticated></shiro:notAuthenticated> //未认证  执行标签体内容
//授权
//基于角色
<shiro:hasRole name="super"></shiro:hasRole>

//有任意角色都展示
<shiro:hasAnyRoles name="admin,super"></shiro:hasAnyRoles>

//基于资源
<shiro:hasPermission name="user:delete"></shiro:hasPermission>

5.示例

5.1.Controller

package com.baizhi.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/user")
@Controller
public class UserController {

    @RequestMapping("login")
    public String login(String username,String password){

        System.out.println("=="+username);
        System.out.println("=="+password);

        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username,password);

        try {
            subject.login(usernamePasswordToken);
            return "main/main";
        } catch (UnknownAccountException e) {
            System.out.println("用户不存在");

            return "main/login";
        } catch (IncorrectCredentialsException e) {

            System.out.println("密码不正确");

            return "main/login";
        }
    }

    @RequestMapping("logout")
    public String logout(){

        Subject subject = SecurityUtils.getSubject();
        subject.logout();

        return "/main/main";
    }
}

5.2.认证和授权

package com.baizhi.shiro.realm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.authz.aop.AuthorizingAnnotationHandler;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.Arrays;

public class MyRealm extends AuthorizingRealm {

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        //根据Token获取身份信息
        String username = (String) authenticationToken.getPrincipal();
        //根据身份信息查询数据库
        //获取数据库的身份信息与前台的传入的身份信息作对比
        if(username.equals("zhangcn")){
            //从数据库查出的信息   身份信息  凭证信息  盐值  类名
            AuthenticationInfo authenticationInfo=new SimpleAuthenticationInfo("zhangcn","e0504e77b06f5a26faf37d044c65992b", ByteSource.Util.bytes("ABCD"),this.getName());
            return authenticationInfo;
        }
        return null;
    }

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        System.out.println("=========================");
        //给主体赋予角色   权限
        //从数据库查  通过主体查角色,同构角色查权限    ppl主体
        String ppl = (String) principalCollection.getPrimaryPrincipal();

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addRole("super");
        //添加某个权限
        simpleAuthorizationInfo.addStringPermission("user:delete");
        simpleAuthorizationInfo.addStringPermission("user:update");
        simpleAuthorizationInfo.addStringPermission("user:query");
        //添加权限集合
        simpleAuthorizationInfo.addStringPermissions(Arrays.asList("user:delete","user:update","user:query"));

        return simpleAuthorizationInfo;
    }

}

5.3.配置

package com.baizhi.shiro.conf;

import com.baizhi.shiro.realm.MyRealm;
import com.sun.org.apache.bcel.internal.generic.RETURN;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;

@Configuration
public class ShiroFilterConf {

    //创建shiro过滤器
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(SecurityManager securityManager){

        //shiro过滤器
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        //过滤器默认不拦截   想要拦截需要配置拦截规则    /* *.do

        HashMap<String, String> map = new HashMap<>();
        //配置拦截规则
        map.put("/**","authc");
        map.put("/user/login","anon");
        map.put("/main/main.jsp","anon");
        //设置跳转页面
        shiroFilterFactoryBean.setLoginUrl("/main/login.jsp");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

        return shiroFilterFactoryBean;
    }

    //创建安全管理器
    @Bean
    public SecurityManager getSecurityManager(Realm realm,EhCacheManager ehCacheManager){

        //安全管理器
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setCacheManager(ehCacheManager);
        defaultWebSecurityManager.setRealm(realm);
        return defaultWebSecurityManager;
    }

    //配置自定义realm
    @Bean
    public Realm getRealm(CredentialsMatcher credentialsMatcher){
        MyRealm myRealm = new MyRealm();
        //将凭证匹配器 放入Realm
        myRealm.setCredentialsMatcher(credentialsMatcher);
        return myRealm;
    }

    //配置凭证匹配器
    @Bean
    public CredentialsMatcher getCredentialsMatcher(){

        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashIterations(1024);
        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        return hashedCredentialsMatcher;
    }
    //配置shiro缓存
    @Bean
    public EhCacheManager getEhCacheManager(){
        EhCacheManager ehCacheManager = new EhCacheManager();
        return ehCacheManager;
    }


}

5.4.jsp

<%@page pageEncoding="UTF-8" isELIgnored="false" contentType="text/html; UTF-8" %>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="path" value="${pageContext.request.contextPath}" />
<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body align="center">

        <h1>持明法州后台管理系统</h1>
        <shiro:authenticated>
            您好!<font style="color: red"><strong><shiro:principal/></strong></font>欢迎登录本系统&emsp;&emsp;
            <strong><a href="${path}/user/logout">退出</a></strong><br>
            <ul>
                <li>轮播图管理</li>
                <li>上师管理</li>
                <li>专辑管理</li>
                <li>文章管理</li>
                <shiro:hasAnyRoles name="admin,super">
                    <li>用户管理</li>
                </shiro:hasAnyRoles>
                <shiro:hasRole name="super">
                    管理员管理
                    <hr>
                    <shiro:hasPermission name="user:query">增</shiro:hasPermission>
                    <shiro:hasPermission name="user:delete">删</shiro:hasPermission>
                    <shiro:hasPermission name="user:update">改</shiro:hasPermission>
                    <shiro:hasPermission name="user:insert">查</shiro:hasPermission>
                </shiro:hasRole>
            </ul>
        </shiro:authenticated>

        <shiro:notAuthenticated>
            <a href="${path}/main/login.jsp">您还没有登录,请登录本系统,登陆之后可以浏览更多内容</a>
        </shiro:notAuthenticated>

    </body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值