============= 后端_身份认证 ============= 1 添加账户概要类 /src/main/java/com/weihome/barblog/shiro/AccountProfile.java: /** * 账户概要类 */ @Data public class AccountProfile implements Serializable { private Long id; private String username; private String avatar; private String email; } 2 添加账户域类 /src/main/java/com/weihome/barblog/shiro/AccountRealm.java: /** * 账户域类 */ @Component public class AccountRealm extends AuthorizingRealm { @Autowired JwtUtils jwtUtils; @Autowired UserService userService; @Override public boolean supports(AuthenticationToken authcToken) { return authcToken instanceof JwtToken; } @Override protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { return null; } // 身份认证过程中调用此方法 @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken authcToken) throws AuthenticationException { JwtToken jwtToken = (JwtToken) authcToken; String userId = jwtUtils.getClaimByToken( (String) jwtToken.getPrincipal()).getSubject(); User user = userService.getById(Long.valueOf(userId)); if (user == null) throw new UnknownAccountException("账户不存在"); if (user.getStatus() == -1) throw new LockedAccountException("账户已锁定"); AccountProfile profile = new AccountProfile(); BeanUtil.copyProperties(user, profile); // 返回包含用户基本信息、令牌字符串等在内的认证信息对象 return new SimpleAuthenticationInfo( profile, jwtToken.getCredentials(), getName()); } } 3 添加Shiro配置类 /src/main/java/com/weihome/barblog/config/ShiroConfig.java: /** * Shiro配置类 */ @Configuration public class ShiroConfig { @Autowired JwtFilter jwtFilter; // JWT过滤器 @Bean public SessionManager sessionManager( RedisSessionDAO redisSessionDAO) { DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); // inject redisSessionDAO sessionManager.setSessionDAO(redisSessionDAO); return sessionManager; } @Bean public SessionsSecurityManager securityManager( AccountRealm accountRealm, SessionManager sessionManager, RedisCacheManager redisCacheManager) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(accountRealm); // 账户域 -> 安全管理器 //inject sessionManager securityManager.setSessionManager(sessionManager); // inject redisCacheManager securityManager.setCacheManager(redisCacheManager); return securityManager; } @Bean public ShiroFilterChainDefinition shiroFilterChainDefinition() { DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition(); Map filterMap = new LinkedHashMap<>(); filterMap.put("/**", "jwt"); // /** -> jwt chainDefinition.addPathDefinitions(filterMap); return chainDefinition; } @Bean("shiroFilterFactoryBean") public ShiroFilterFactoryBean shiroFilterFactoryBean( SecurityManager securityManager, ShiroFilterChainDefinition shiroFilterChainDefinition) { ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); shiroFilter.setSecurityManager(securityManager); Map filters = new HashMap<>(); filters.put("jwt", jwtFilter); // jwt -> JWT过滤器 shiroFilter.setFilters(filters); Map filterMap = shiroFilterChainDefinition.getFilterChainMap(); shiroFilter.setFilterChainDefinitionMap(filterMap); return shiroFilter; } } 经过以上配置,Shiro将持有账户域和JWT过滤器,并在适当的时候调用其中的方法: - 判断接受还是拒绝请求 - 创建JWT令牌 - 身份认证失败时响应包含异常信息的Json字符串 - 获取包含用户基本信息、令牌字符串等在内的认证信息对象