SpringBoot整合shiro+鉴权过程+登录接口

  1. 加入maven依赖

<dependency>
    <groupId>org.apache.shirogroupId>
    <artifactId>shiro-coreartifactId>
    <version>${shiro.version}version>
dependency>
<dependency>
    <groupId>org.apache.shirogroupId>
    <artifactId>shiro-springartifactId>
    <version>${shiro.version}version>
dependency>
<dependency>
    <groupId>org.apache.shirogroupId>
    <artifactId>shiro-ehcacheartifactId>
    <version>${shiro.version}version>
dependency>
  1. 自定义Realm
package com.tally.auth;

import com.tally.modules.base.db.TUserInfoEntity;
import com.tally.modules.base.db.TUserTokenEntity;
import com.tally.modules.base.service.ITUserInfoService;
import com.tally.modules.base.service.ITUserTokenService;
import com.tally.shareEntity.ShareUserEntity;
import com.tally.utils.TLMap;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
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.stereotype.Component;

import java.util.Set;


/**
* Created with IntelliJ IDEA.
* Author: Usopp.tsui
* Date: 2020/11/19
* Time: 22:20
* Description:
*/
@Component
public class AuthRealm extends AuthorizingRealm {
   
   @Autowired
   private ITUserInfoService  itUserInfoService;
   @Autowired
   private ITUserTokenService itUserTokenService;

   //授权(验证权限时调用)
   @Override
   protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
   
       ShareUserEntity<TUserTokenEntity, TUserInfoEntity> shareUserEntity = (ShareUserEntity) principalCollection.getPrimaryPrincipal();
       if (null == shareUserEntity) {
   
           throw new LockedAccountException("当前用户权限过期,请重新登录!");
       }
       //token时间校验
       TUserTokenEntity tokenEntity = shareUserEntity.getT();
       this.verifiedToken(tokenEntity);
       //用户账号校验
       TUserInfoEntity userEntity = shareUserEntity.getU();
       this.verifiedUser(userEntity);
       //将授权的permission名称集合赋予给shiro
       Set<String> permsSet = shareUserEntity.getPermsSet();
       SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
       info.addStringPermissions(permsSet);
       TLMap.setToken(tokenEntity.getToken());
       TLMap.setUserId(userEntity.getUserId());
       TLMap.setMobile(userEntity.getMobile());
       return info;
   }

   //认证登录(登录时调用)
   @Override
   protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
   
       UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;
       String accessToken = String.valueOf(usernamePasswordToken.getPassword());
       TUserTokenEntity tokenEntity = itUserTokenService.queryByToken(accessToken);
       //token校验
       this.verifiedToken(tokenEntity);
       TUserInfoEntity userInfoEntity = itUserInfoService.queryByUserId(tokenEntity.getUserId());
       //用户状态校验
       this.verifiedUser(userInfoEntity);
       //获取该用户权限列表
       Set<String> permsSet = userInfoEntity.getPermSet();
       //将当前用户,票据,权限,企业源全部封入map中进行共享
       ShareUserEntity<TUserTokenEntity, TUserInfoEntity> shareUserEntity = new ShareUserEntity();
       shareUserEntity.setT(tokenEntity);
       shareUserEntity.setU(userInfoEntity);
       shareUserEntity.setPermsSet(permsSet);
       ShareUserEntity<TUserTokenEntity, TUserInfoEntity> userEntity = new ShareUserEntity();
       userEntity.setT(tokenEntity);
       userEntity.setU(userInfoEntity);
       TLMap.setToken(tokenEntity.getToken());
       TLMap.setUserId(userInfoEntity.getUserId());
       TLMap.setMobile(userInfoEntity.getMobile());
       //这里直接用token进行对比,第二个地方传入的token,而不是数据库中的密码
       return new SimpleAuthenticationInfo(userEntity, tokenEntity.getToken(), this.getClass().getName());
   }

   /**
    * 用户校验方法
    *
    * @param userEntity
    */
   private void verifiedUser(TUserInfoEntity userEntity) {
   
       //禁用或者被删除
       if (!userEntity.getStatus().equals("0")) {
   
           try {
   
               SecurityUtils.getSubject().logout();
           } catch (Exception e) {
   

           }
           throw new LockedAccountException("账号已被禁用!申诉请联系管理员!");
       }
       if (!userEntity.getUserId().equals(TLMap.getUserId())) {
   
           try {
   
               SecurityUtils.getSubject().logout();
           } catch (Exception e) {
   

           }
           throw new LockedAccountException("账号涉嫌违规或违法操作!");
       }
   }

   /**
    * token校验方法
    *
    * @param tokenEntity
    */
   private void verifiedToken(TUserTokenEntity tokenEntity) {
   
       if (tokenEntity == null || tokenEntity.getExpireTime().getTime() < System.currentTimeMillis()) {
   
           try {
   
               SecurityUtils.getSubject().logout();
           } catch (Exception e) {
   

           }
           throw new IncorrectCredentialsException("token失效,请重新登录");
       }
       //与当前线程的token不相等
       if (!tokenEntity.getToken().equals(TLMap.getToken())) {
   
           try {
   
               SecurityUtils.getSubject().logout();
           } catch (Exception e) {
   

           }
           throw new IncorrectCredentialsException("token失效,请重新登录");
       }
   }

}
  1. 自定义CredentialMatcher
package com.tally.auth;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;

/**
* Created with IntelliJ IDEA.
* Author: Usopp.tsui
* Date: 2020/11/19
* Time: 22:46
* Description:
*/
public class CredentialMatcher extends SimpleCredentialsMatcher {
   
   //密码校验规则重写
   @Override
   public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
   
       UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
       String password = new String(usernamePasswordToken.getPassword());
       String dbPassword = (String) info.getCredentials();
       return this.equals(password, dbPassword);
   }
}
  1. 创建shiro配置(ShiroConfig)
package com.tally.config;

import com.tally.auth.AuthRealm;
import com.tally.auth.CredentialMatcher;
import com.tally.init.filter.OAuth2Filter;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
1. Created with IntelliJ IDEA.
2. Author: Usopp.tsui
3. Date: 2020/11/19
4. Time: 22:49
5. Description:
*/
@Configuration
public class ShiroConfig {
   
   //定义shiroFilter,传入securityManager
   @Bean("shiroFilter")
   public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager securityManager) {
   
       ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
       shiroFilter.setSecurityManager(securityManager);
       //oauth过滤 加入自定义的过滤器
       Map<String, Filter> filters = new HashMap<>();
       filters.put("oauth2", new OAuth2Filter());
       shiroFilter.setFilters(filters);
       //key:代

你可能感兴趣的:(Spring,shiro,spring,boot)