当前位置: 代码迷 >> 综合 >> springboot 集成shiro
  详细解决方案

springboot 集成shiro

热度:91   发布时间:2024-01-29 10:23:39.0

springboot中集成shiro只需要两个类:一个是shiroConfig类,一个是CustonRealm类。

ShiroConfig类:

package com.cj.shirodemo.config;import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
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.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;import java.util.LinkedHashMap;
import java.util.Map;@Configuration
public class ShiroConfig {@Beanpublic ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(securityManager);shiroFilterFactoryBean.setLoginUrl("/login");shiroFilterFactoryBean.setUnauthorizedUrl("/notRole");Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();// <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->filterChainDefinitionMap.put("/static/**", "anon");filterChainDefinitionMap.put("/login", "anon");filterChainDefinitionMap.put("/", "anon");filterChainDefinitionMap.put("/swagger-ui.html", "anon");filterChainDefinitionMap.put("/v2/api-docs", "anon");//主要这行代码必须放在所有权限设置的最后,不然会导致所有 url 都被拦截 剩余的都需要认证filterChainDefinitionMap.put("/**", "authc");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;}@Beanpublic SecurityManager securityManager() {DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();defaultSecurityManager.setRealm(customRealm());return defaultSecurityManager;}@Beanpublic CustomRealm customRealm() {CustomRealm customRealm = new CustomRealm();return customRealm;}
}

CustonRealm类:

import com.wsl.bean.Permissions;
import com.wsl.bean.Role;
import com.wsl.bean.User;
import com.wsl.service.LoginService;
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;public class CustomRealm extends AuthorizingRealm {@Autowiredprivate LoginService loginService;@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {//获取登录用户名String name = (String) principalCollection.getPrimaryPrincipal();//根据用户名去数据库查询用户信息User user = loginService.getUserByName(name);//添加角色和权限SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();for (Role role : user.getRoles()) {//添加角色simpleAuthorizationInfo.addRole(role.getRoleName());//添加权限for (Permissions permissions : role.getPermissions()) {simpleAuthorizationInfo.addStringPermission(permissions.getPermissionsName());}}return simpleAuthorizationInfo;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {//加这一步的目的是在Post请求的时候会先进认证,然后在到请求if (authenticationToken.getPrincipal() == null) {return null;}//获取用户信息String userName= authenticationToken.getPrincipal().toString();User user = loginService.getUserByName(userName);if (user == null) {//这里返回后会报出对应异常return null;} else {//这里验证authenticationToken和simpleAuthenticationInfo的信息SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userName, user.getPassword(), getName());return simpleAuthenticationInfo;}}
}

说明:
自定义的Realm类继承AuthorizingRealm类,并且重载doGetAuthorizationInfo和doGetAuthenticationInfo两个方法。


doGetAuthorizationInfo: 权限认证,即登录过后,每个身份不一定,对应的所能看的页面也不一样。
doGetAuthenticationInfo:身份认证。即登录通过账号和密码验证登陆人的身份信息。