(3) shiro实战-ssm架构系统-代码部分

目录

1、新增用户并加密

1.1 Table DDL

 1.2 Control

1.3 Service

2、用户登录并验证

2.1 controller

2.2 UserRealm

2.3 RetryLimitHashedCredentialsMatcher

3、用户登出


 

扫描二维码关注公众号,回复: 9559615 查看本文章

结构图:

1、新增用户并加密

1.1 Table DDL

CREATE TABLE `user` (
  `id` varchar(30) NOT NULL,
  `name` varchar(30) DEFAULT NULL,
  `sex` varchar(30) DEFAULT NULL,
  `username` varchar(32) DEFAULT NULL,
  `password` varchar(32) DEFAULT NULL,
  `role` varchar(32) DEFAULT NULL,
  `permissions` varchar(100) DEFAULT NULL,
  `Locked` varchar(1) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 1.2 Control

@RequestMapping(value = "/shiro/region", method = RequestMethod.POST)
	@ResponseBody
	public String shiroRegion(String username, String password) {
		User user = new User();
		user.setId("005");
		user.setName("lucy");
		user.setSex("women");
		user.setUsername("005");
		user.setPassword("123");
		user.setRole("admin");
		user.setPermissions("delete");
		user.setLocked("0");
		shiroUserService.AddUser(user);
		return "";
	}

1.3 Service

@Override
	public void AddUser(User user) {
		RandomNumberGenerator randomNumberGenerator = new SecureRandomNumberGenerator();
		String algorithmName = "md5";
		int hashIterations = 2;

         //用用户名作为salt
		String salt = user.getUsername();

		SimpleHash hash = new SimpleHash(algorithmName, user.getPassword(), salt, hashIterations);
		user.setPassword(hash.toHex());
		userMapper.insert(user);
	}

2、用户登录并验证

2.1 controller

@RequestMapping(value = "/shiro/login", method = RequestMethod.POST)
	@ResponseBody
	public String shiroLogin(String username, String password) {
		String error = null;

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

		try {
			subject.login(token);
		} catch (IncorrectCredentialsException ice) {
			// 捕获密码错误异常
			return "密码错误";
		} catch (UnknownAccountException uae) {
			// 捕获未知用户名异常
			return "用户名不存在";
		} catch (ExcessiveAttemptsException eae) {
			// 捕获错误登录过多的异常

			return "登录次数超过5次!";
		}
		User user = shiroUserService.findByUsername(username);
		/**
		 * 登录完成以后,当前用户信息被保存进Session。 这个Session是通过Shiro管理的会话对象,要获取依然必须通过Shiro。
		 * 传统的Session中不存在User对象
		 */
		subject.getSession().setAttribute("user", user);
		return "sucess";
	}

2.2 UserRealm

package com.comqing.common.utils;

public class UserRealm extends AuthorizingRealm {

	// 用户对应的角色信息与权限信息都保存在数据库中,通过UserService获取数据

	@Autowired
	private ShiroUserService userService;

	/**
	 * 提供用户信息返回权限信息
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		String username = (String) principals.getPrimaryPrincipal();
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		// 根据用户名查询当前用户拥有的角色
		String roles = userService.findRoles(username);
		Set<String> roleNames = new HashSet<String>();
		roleNames.add(roles);
		// 将角色名称提供给info
		authorizationInfo.setRoles(roleNames);

		// 根据用户名查询当前用户权限
		String permissions = userService.findPermissions(username);
		Set<String> permissionNames = new HashSet<String>();
		permissionNames.add(permissions);
		// 将权限名称提供给info
		authorizationInfo.setStringPermissions(permissionNames);

		return authorizationInfo;
	}

	/**
	 * 提供账户信息返回认证信息
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String username = (String) token.getPrincipal();
		User user = userService.findByUsername(username);
		if (user == null) {
			// 用户名不存在抛出异常
			throw new UnknownAccountException();
		}
		if (user.getLocked() == "0") {
			// 用户被管理员锁定抛出异常
			throw new LockedAccountException();
		}
		// 当前 Realm 的 name
		String realmName = this.getName();
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(),
				user.getPassword(), ByteSource.Util.bytes(user.getUsername()), realmName);

		return authenticationInfo;
	}
}

2.3 RetryLimitHashedCredentialsMatcher

package com.comqing.common.utils;


public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher {

	// 声明一个缓存接口,这个接口是Shiro缓存管理的一部分,它的具体实现可以通过外部容器注入
	private Cache<String, AtomicInteger> passwordRetryCache;

	public RetryLimitHashedCredentialsMatcher(CacheManager cacheManager) {
		passwordRetryCache = cacheManager.getCache("passwordRetryCache");
	}

	@Override
	public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
		String username = (String) token.getPrincipal();
		AtomicInteger retryCount = passwordRetryCache.get(username);
		if (retryCount == null) {
			retryCount = new AtomicInteger(0);
			passwordRetryCache.put(username, retryCount);
		}
		// 自定义一个验证过程:当用户连续输入密码错误5次以上禁止用户登录一段时间
		if (retryCount.incrementAndGet() > 5) {
			throw new ExcessiveAttemptsException();
		}
		boolean match = super.doCredentialsMatch(token, info);
		if (match) {
			passwordRetryCache.remove(username);
		}
		return match;
	}
}

3、用户登出

参考:http://blog.csdn.net/clj198606061111/article/details/24185023

@RequestMapping(value = "/shiro/logout", method = RequestMethod.POST)
	@ResponseBody
	public String shiroLogout() {
		Subject subject = SecurityUtils.getSubject();
		if (subject.isAuthenticated()) {
			subject.logout(); // session 会销毁,在SessionListener监听session销毁,清理权限缓存
		}
		return "sucess";
	}
发布了116 篇原创文章 · 获赞 14 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/allensandy/article/details/104397708