123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- package com.fd.shiro;
- import com.fd.entity.User;
- import com.fd.repository.UserRepository;
- import lombok.extern.log4j.Log4j2;
- 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.realm.AuthorizingRealm;
- import org.apache.shiro.subject.PrincipalCollection;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.stereotype.Service;
- import java.util.Arrays;
- import java.util.HashSet;
- import java.util.Set;
- /**
- * 配置不校验的话,是不会走这个方法的
- */
- @Log4j2
- @Service
- public class MyRealm extends AuthorizingRealm {
- @Autowired
- private UserRepository userRepository;
- @Autowired
- private RedisTemplate redisTemplate;
- /**
- * 大坑!,必须重写此方法,不然Shiro会报错
- */
- @Override
- public boolean supports(AuthenticationToken token) {
- return token instanceof JWTToken;
- }
- /**
- * 只有当需要检测用户权限的时候才会调用此方法,例如checkRole,checkPermission之类的
- *
- * principals: 是token
- */
- @Override
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
- String username = JWTUtil.getUsername(principals.toString());
- User user = userRepository.findByUsername(username);
- SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
- simpleAuthorizationInfo.addRole(user.getRole());
- // db 添加权限时,用“,”隔开
- Set<String> permission = new HashSet<>(Arrays.asList(user.getPermission().split(",")));
- simpleAuthorizationInfo.addStringPermissions(permission);
- return simpleAuthorizationInfo;
- }
- /**
- * 默认使用此方法进行用户名正确与否验证,错误抛出异常即可。
- */
- @Override
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
- // log.warn("run doGetAuthenticationInfo");
- String token = (String) auth.getCredentials();
- // log.warn("token: {}", token);
- // 解密获得username,用于和数据库进行对比
- String username = JWTUtil.getUsername(token);
- if (username == null) {
- log.info("error token username");
- throw new AuthenticationException("token invalid");
- }
- User user = userRepository.findByUsername(username);
- if (user == null) {
- log.info("error token user");
- throw new AuthenticationException("User didn't existed!");
- }
- // 校验请求token是否跟redis token一致
- String redisToken = (String) redisTemplate.opsForValue().get(user.getUsername());
- if (!token.equals(redisToken)) {
- log.info("error token redis");
- throw new AuthenticationException("token invalid");
- }
- if (! JWTUtil.verify(token, username, user.getPassword())) {
- log.info("error token username or password");
- throw new AuthenticationException("token invalid");
- }
- // log.warn("end doGetAuthenticationInfo");
- return new SimpleAuthenticationInfo(token, token, "my_realm");
- }
- }
|