• shiro的配置详解


    1.下载shiro

    http://shiro.apache.org/download.html

    2.shiro架构的核心内容介绍

    Subject__应用代码直接交互的对象是Subject,****与****Subject 的所有交互都会委托给 SecurityManager

    ②SecurityManager******安全管理器;****即所有与安全有关的操作都会与******SecurityManager**** 交互;且其管理着所有Subject

    ③Realm********Shiro 从 ****Realm 获取安全数据(如用户、角色、权限),****就是说 SecurityManager 要验证用户身份,那么它需要从 Realm 获取相应的用户进行比较以确定用户身份是否合法;也需要从 Realm 得到用户相应的角色/权限进行验证用户是否能进行操作.

    3.引入shiro依赖

    
    		1.2.3
    	
    
    		
    			net.sf.ehcache
    			ehcache-core
    			2.6.6
    		
    		
    			org.apache.shiro
    			shiro-ehcache
    			${shiro.version}
    		
    		
    		
    			org.apache.shiro
    			shiro-core
    			${shiro.version}
    		
    		
    			org.apache.shiro
    			shiro-web
    			${shiro.version}
    		
    		
    			org.apache.shiro
    			shiro-spring
    			${shiro.version}
    		
    		
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    4.首先在web.xml中加入shiro过滤器

    
        shiroFilter
        org.springframework.web.filter.DelegatingFilterProxy
        
          targetFilterLifecycle
          true
        
    
    
        shiroFilter
        /*
        REQUEST
        FORWARD
        ERROR
        INCLUDE
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    5.添加shiro与spring集成的配置文件application-shiro.xml

    
    
    
    	
    	
    		
    		
    		
    		
    		
    		
    	
    
    	
    		
    	
    	
    	
    		
    	
    
    	
    	
    		
    		
    		
    		
    		
    		
    		
    		
    		
    		
    	
    
    	
    	
    
    	
    	
    	
    		
    	
    
        
    	
    		
    		
    		
    		
    
    		
    		
    			
    				/**/*login*/**=anon
    				/resources/**=anon
    				/**/*logout*/**=logout
    				/**=user
    			
    		
    	
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82

    6.缓存管理器ehcache.xml

    
    
    
    	
    	
    	
    	????
    	
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    7.自定义realm

    package com.plat.shiro;
    
    import javax.annotation.Resource;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.LockedAccountException;
    import org.apache.shiro.authc.SimpleAuthenticationInfo;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.realm.jdbc.JdbcRealm;
    import org.apache.shiro.session.Session;
    
    import com.plat.commons.model.SysUser;
    import com.plat.service.SysUserService;
    
    public class CustomJdbcRealm extends JdbcRealm {
    
    	@Resource
    	private SysUserService sysUserService;
    	
    	@Override
    	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    		System.out.println("------doGetAuthenticationInfo-------");
    		/**
    		 * js --> sysUser/login --> Subject.login(UsernamepasswordToken) --> CustomJdbcRealm
    		 */
    		
    		UsernamePasswordToken usernamePasswordToken =(UsernamePasswordToken) token;
    		//获取登录账号
    		String account=usernamePasswordToken.getUsername();
    		SysUser sysUser=sysUserService.findByAccount(account);
    		if(sysUser==null) {
    			throw new UnknownAccountException();
    		}
    		//判断用户名和密码是否正确
    		if(!sysUser.getPassword().equals(new String (usernamePasswordToken.getPassword()))) {
    			throw new IncorrectCredentialsException();
    		}
    		//判断用户是否被禁用
    		if(sysUser.getIsUse()==0) {
    			throw new LockedAccountException();
    		}
    		
    		//用户登录成功,将用户保存到session中
    		Session session= SecurityUtils.getSubject().getSession();
    		session.setAttribute("sysUser", sysUser);
    		
    		//参数1:Subject.getPrincipal()获取到的就是参数一传入的内容
    		//参数2:shiro进行用户信息比对的时候使用的密码
    		//参数3:realm名称,getName方法自动生成一个realm的名称
    		return new SimpleAuthenticationInfo(account,sysUser.getPassword(),getName());
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    8.登录方法

    @RequestMapping("/login")
    	@ResponseBody
    	public String login(String account,String password) {
    		//返回信息
    		String message = "";
    		if(!isNotNull(account)) {
    			message="登录账号不能为空";
    		}
    		
    		if(message=="" && !isNotNull(password)) {
    			message="登录密码不能为空";
    		}
    		//登录
    		if(!isNotNull(message)) {
    			Subject currentUser=SecurityUtils.getSubject();
    			
    			//加密密码
    			String md5Password = DigestUtil.hmacSign(password, DigestUtil.digest("heheda"));
    			
    			UsernamePasswordToken upToken=
    					new UsernamePasswordToken(account,md5Password);
    			//记住我
    			//upToken.setRememberMe(true);
    			try {
                    //进入shiro的登录,此时将进入自定义的realm中进行安全验证
    				currentUser.login(upToken);
    				message="success";
    			}catch (UnknownAccountException uae) {
    				message="账号不存在";
    			}catch (IncorrectCredentialsException ice) {
    				message="用户名或者密码错误";
    			}catch (LockedAccountException lae) {
    				message="账号已被锁定";
    			} catch (AuthenticationException e) {
    				message="登录异常,请稍后再试!!";
    				e.printStackTrace();
    			}
    		}
    		return message;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    9.MD5

    package com.plat.commons.util;
    
    import java.io.UnsupportedEncodingException;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.Arrays;
    
    public class DigestUtil {
    
    	private static String encodingCharset = "UTF-8";
    
    	/**
    	 * @param aValue
    	 * @param aKey
    	 * @return
    	 */
    	public static String hmacSign(String aValue, String aKey) {
    		byte k_ipad[] = new byte[64];
    		byte k_opad[] = new byte[64];
    		byte keyb[];
    		byte value[];
    		try {
    			keyb = aKey.getBytes(encodingCharset);
    			value = aValue.getBytes(encodingCharset);
    		} catch (UnsupportedEncodingException e) {
    			keyb = aKey.getBytes();
    			value = aValue.getBytes();
    		}
    
    		Arrays.fill(k_ipad, keyb.length, 64, (byte) 54);
    		Arrays.fill(k_opad, keyb.length, 64, (byte) 92);
    		for (int i = 0; i < keyb.length; i++) {
    			k_ipad[i] = (byte) (keyb[i] ^ 0x36);
    			k_opad[i] = (byte) (keyb[i] ^ 0x5c);
    		}
    
    		MessageDigest md = null;
    		try {
    			md = MessageDigest.getInstance("MD5");
    		} catch (NoSuchAlgorithmException e) {
    
    			return null;
    		}
    		md.update(k_ipad);
    		md.update(value);
    		byte dg[] = md.digest();
    		md.reset();
    		md.update(k_opad);
    		md.update(dg, 0, 16);
    		dg = md.digest();
    		return toHex(dg);
    	}
    
    	public static String toHex(byte input[]) {
    		if (input == null)
    			return null;
    		StringBuffer output = new StringBuffer(input.length * 2);
    		for (int i = 0; i < input.length; i++) {
    			int current = input[i] & 0xff;
    			if (current < 16)
    				output.append("0");
    			output.append(Integer.toString(current, 16));
    		}
    
    		return output.toString();
    	}
    
    	/**
    	 * 
    	 * @param args
    	 * @param key
    	 * @return
    	 */
    	public static String getHmac(String[] args, String key) {
    		if (args == null || args.length == 0) {
    			return (null);
    		}
    		StringBuffer str = new StringBuffer();
    		for (int i = 0; i < args.length; i++) {
    			str.append(args[i]);
    		}
    		return (hmacSign(str.toString(), key));
    	}
    
    	/**
    	 * @param aValue
    	 * @return
    	 */
    	public static String digest(String aValue) {
    		aValue = aValue.trim();
    		byte value[];
    		try {
    			value = aValue.getBytes(encodingCharset);
    		} catch (UnsupportedEncodingException e) {
    			value = aValue.getBytes();
    		}
    		MessageDigest md = null;
    		try {
    			md = MessageDigest.getInstance("SHA");
    		} catch (NoSuchAlgorithmException e) {
    			e.printStackTrace();
    			return null;
    		}
    		return toHex(md.digest(value));
    
    	}
    
    	public static void main(String[] args) {
            // 参数1: 明文(要加密的数据) 参数2: 密钥
    		System.out.println(DigestUtil.hmacSign("11111", "dddd"));
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
  • 相关阅读:
    《统计学习方法》 第九章 EM算法(原理+代码)
    web安全进阶 - - - 流量隐藏
    手把手教你做个智能加湿器(一)
    YOLOv5、v7改进之二十六:改进特征融合网络PANet为ASFF自适应特征融合网络
    计算机毕业设计-微信小程序文学小说阅读销售系统
    浅析linux内核网络协议栈--linux bridge(二)
    SpringBoot整合Swagger3和Knife4j及使用
    Qt httpclient
    计算机网络 | 网络层(数据平面)
    LeetCode 452. 用最少数量的箭引爆气球
  • 原文地址:https://blog.csdn.net/m0_54864585/article/details/126496471