shiro 使用

  •  shiro 核心架构

  1. Subject(主体):与软件交互的一个特定的实体(用户、第三方服务等)。
  2. SecurityManager(安全管理器) :Shiro 的核心,用来协调管理组件工作。
  3. Authenticator(认证管理器):负责执行认证操作
  4. Authorizer(授权管理器):负责授权检测
  5. SessionManager(会话管理):负责创建并管理用户 Session 生命周期,提供一个强有力的 Session 体验。
  6. SessionDAO:代表 SessionManager 执行 Session 持久(CRUD)动作,它允许任何存储的数据挂接到 session 管理基础上。
  7. CacheManager(缓存管理器):提供创建缓存实例和管理缓存生命周期的功能
  8. Cryptography(加密管理器):提供了加密方式的设计及管理。
  9. Realms(领域对象):是shiro和你的应用程序安全数据之间的桥梁。

 

  • shiro 认证

  1. 系统调用subject的login方法将用户信息提交给SecurityManager
  2. SecurityManager将认证操作委托给认证器对象Authenticator
  3. Authenticator将用户输入的身份信息传递给Realm。
  4. Realm访问数据库获取用户信息然后对信息进行封装并返回。
  5. Authenticator 对realm返回的信息进行身份认证。

 

  • shiro 授权

  1. 系统调用subject相关方法将用户信息(例如isPermitted)递交给SecurityManager
  2. SecurityManager将权限检测操作委托给Authorizer对象,Authorizer将用户信息委托给realm.
  3. Realm访问数据库获取用户权限信息并封装。
  4. Authorizer对用户授权信息进行判定。

 


  • 添加依赖
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.3.2</version>
</dependency>

 

  • web.xml
	<!-- 
		1)	targetBeanName 名字由DelegatingFilterProxy对象底层设置并读取。
		2)	shiroFilterFactory 名字要与ShiroFilterFactoryBean配置的id相同。
	 -->
	<filter>
		<filter-name>shiroFilter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
		<init-param>
			<param-name>targetBeanName</param-name>
			<param-value>shiroFilterFactory</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>shiroFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
  • spring-shiro.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="true"
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="  
       http://www.springframework.org/schema/beans   
       http://www.springframework.org/schema/beans/spring-beans.xsd  
       http://www.springframework.org/schema/mvc   
       http://www.springframework.org/schema/mvc/spring-mvc.xsd   
       http://www.springframework.org/schema/tx   
       http://www.springframework.org/schema/tx/spring-tx.xsd   
       http://www.springframework.org/schema/aop 
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/util 
       http://www.springframework.org/schema/util/spring-util.xsd
       http://www.springframework.org/schema/data/jpa 
       http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">
       
	<!-- shiro过滤与认证 -->
	<bean id="shiroFilterFactory" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="SecurityManager" ref="securityManager" />
		<property name="LoginUrl" value="/doLoginUI.do" />
		<!-- 设置请求过滤规则 -->
		<property name="FilterChainDefinitionMap">
			<map>
				<!--anon 匿名可访问,authc 必须认证,假如添加了记住我功能以后需要设置为user -->
				<entry key="/bower_components/**" value="anon" />
				<entry key="/build/**" value="anon" />
				<entry key="/dist/**" value="anon" />
				<entry key="/plugins/**" value="anon" />
				<entry key="/user/doLogin.do" value="anon" />
				<entry key="/doLogout.do" value="logout" />
				<!--<entry key="/**" value="authc" /> 必须认证 -->
				<entry key="/**" value="user" />
			</map>
		</property>
	</bean>
	
	<!-- 安全管理器 -->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<!-- 认证与授权,在 ShiroUserRealm 类中重写各自方法-->
		<property name="Realm" ref="shiroUserRealm" />
		<!-- shiro缓存 -->
		<property name="CacheManager" ref="cacheManager" />
		<!-- remember me -->
		<property name="RememberMeManager" ref="rememberMeManager" />
		<!-- session -->
		<property name="sessionManager" ref="sessionManager"/>
	</bean>

	<!-- shiro授权 -->
	<!-- 授权属性的Advisor配置 -->
	<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
		<property name="SecurityManager" ref="securityManager" />
	</bean>
	<!-- 配置bean对象的生命周期管理 -->
	<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean>
	<!-- 通过此配置要为目标业务对象创建代理对象 -->
	<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
		depends-on="lifecycleBeanPostProcessor">
	</bean>


	<!-- shiro缓存 -->
	<bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />

	<!-- remember me -->
	<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
		<constructor-arg value="rememberMe" />
		<!-- 7天,采用spring el表达式来计算,方便修改 -->
		<property name="maxAge" value="#{7 * 24 * 60 * 60}" />
	</bean>
	<bean id="rememberMeManager"
		class="org.apache.shiro.web.mgt.CookieRememberMeManager">
		<property name="cookie" ref="rememberMeCookie" />
	</bean>

	<!-- shiro结合Session会话管理器 start -->
	<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
		<!-- session的失效时长,单位毫秒 1小时: 3600000, itzixi站点设置以 6小时 为主:21600000 -->
		<!-- 设置全局会话超时时间,默认30分钟,即如果30分钟内没有访问会话将过期 1800000 -->
		<property name="globalSessionTimeout" value="21600000" />
		<!-- 删除失效的session -->
		<property name="deleteInvalidSessions" value="true" />
		<!-- 是否开启会话验证器,默认是开启的 -->
		<property name="sessionValidationSchedulerEnabled" value="true" />
	</bean>
	
</beans>
  • service 层新建类 ShiroUserRealm 继承AuthorizingRealm  接口,重写3个方法
@Service
public class ShiroUserRealm extends AuthorizingRealm {

	@Autowired
	private SysUserDao sysUserDao;

	@Autowired
	private SysUserRoleDao sysUserRoleDao;

	@Autowired
	private SysRoleMenuDao sysRoleMenuDao;

	@Autowired
	private SysMenuDao sysMenuDao;

	/** 通过此方法完成授权信息的获取及封装,在service 层的方法使用@RequiresPermissions("sys:user:valid")来允许拥有sys:user:valid 权限的用户调用方法 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		// 1.获取登录用户信息,例如用户id
		SysUser user = (SysUser) principals.getPrimaryPrincipal();
		Integer userId = user.getId();
		
		// 2.基于用户id获取用户拥有的角色(sys_user_roles)
		List<Integer> roleIds = sysUserRoleDao.findRoleIdsByUserId(userId);
		if (roleIds == null || roleIds.size() == 0)
			throw new AuthorizationException();
		
		// 3.基于角色id获取菜单id(sys_role_menus)
		Integer[] array = {};
		List<Integer> menuIds = sysRoleMenuDao.findMenuIdsByRoleIds(roleIds.toArray(array));
		if (menuIds == null || menuIds.size() == 0)
			throw new AuthorizationException();
		
		// 4.基于菜单id获取权限标识(sys_menus)
		List<String> permissions = sysMenuDao.findPermissions(menuIds.toArray(array));
		
		// 5.对权限标识信息进行封装并返回
		Set<String> set = new HashSet<>();
		for (String per : permissions) {
			if (!StringUtils.isEmpty(per)) {
				set.add(per);
			}
		}
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.setStringPermissions(set);
		return info;// 返回给授权管理器
	}

	/**
	 * 设置凭证匹配器(与用户添加操作使用相同的加密算法)
	 */
	@Override
	public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
		// 构建凭证匹配对象
		HashedCredentialsMatcher cMatcher = new HashedCredentialsMatcher();
		// 设置加密算法
		cMatcher.setHashAlgorithmName("MD5");
		// 设置加密次数
		cMatcher.setHashIterations(1);

		super.setCredentialsMatcher(cMatcher);
	}

	/**
	 * 通过此方法完成认证数据的获取及封装,系统 底层会将认证数据传递认证管理器,由认证 管理器完成认证操作。
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

		// 1.获取用户名(用户页面输入)
		UsernamePasswordToken upToken = (UsernamePasswordToken) token;
		String username = upToken.getUsername();
		// 2.基于用户名查询用户信息
		SysUser user = sysUserDao.findUserByUserName(username);
		// 3.判定用户是否存在
		if (user == null)
			throw new UnknownAccountException("账户不存在");
		// 4.判定用户是否已被禁用。
		if (user.getValid() == 0)
			throw new LockedAccountException();

		// 5.封装用户信息
		ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());
		// 记住:构建什么对象要看方法的返回值
		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, // principal (身份)
				user.getPassword(), // hashedCredentials,token 存有前端传来的密码,这里是数据库取的密码
				credentialsSalt, // credentialsSalt,每个账号的盐值都不同,所以要从数据库获取账户的盐值
				getName());// realName
		// 6.返回封装结果
		return info;// 返回值会传递给认证管理器(后续
		// 认证管理器会通过此信息完成认证操作)

	}

}
  • 业务Service 层

保存用户,保存密码代码片段

        // 将数据写入数据库,保存密码部分
		String salt = UUID.randomUUID().toString();
		entity.setSalt(salt);
		// 加密
		SimpleHash sHash = new SimpleHash("MD5", entity.getPassword(), salt, 1);
		entity.setPassword(sHash.toHex());

 更新密码

@Override
	public int updatePassword(String password, String newPassword, String cfgPassword) {
		// 1.判定新密码与密码确认是否相同
		if (StringUtils.isEmpty(newPassword))
			throw new IllegalArgumentException("新密码不能为空");
		if (StringUtils.isEmpty(cfgPassword))
			throw new IllegalArgumentException("确认密码不能为空");
		if (!newPassword.equals(cfgPassword))
			throw new IllegalArgumentException("两次输入的密码不相等");
		// 2.判定原密码是否正确
		if (StringUtils.isEmpty(password))
			throw new IllegalArgumentException("原密码不能为空");
		// 获取登陆用户
		SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();//获取的是当前登陆用户
		SimpleHash sh = new SimpleHash("MD5", password, user.getSalt(), 1);
		if (!user.getPassword().equals(sh.toHex()))
			throw new IllegalArgumentException("原密码不正确");
		// 3.对新密码进行加密
		String salt = UUID.randomUUID().toString();
		sh = new SimpleHash("MD5", newPassword, salt, 1);
		// 4.将新密码加密以后的结果更新到数据库
		int rows = sysUserDao.updatePassword(sh.toHex(), salt, user.getId());
		if (rows == 0)
			throw new ServiceException("修改失败");
		return rows;
	}
  • Controller 层
	@RequestMapping("/doLogin")
	@ResponseBody
	public ReturnJson doLogin(boolean isRememberMe, String username, String password) {
		// 1.获取Subject对象
		Subject subject = SecurityUtils.getSubject();
		// 2.通过Subject提交用户信息,交给shiro框架进行认证操作
		// 2.1对用户进行封装
		UsernamePasswordToken token = new UsernamePasswordToken(
				username, // 身份信息
				password);// 凭证信息
		if (isRememberMe) {
			token.setRememberMe(true);
		}
		// 2.2对用户信息进行身份认证
		subject.login(token);
		// 分析:
		// 1)token会传给shiro的SecurityManager
		// 2)SecurityManager将token传递给认证管理器
		// 3)认证管理器会将token传递给realm
		return new ReturnJson("login ok");
	}

  • 另java 类配置shiro
package com.db.common.config;

import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.RememberMeManager;
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.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import com.db.sys.service.realm.ShiroUserRealm;

/** @Configuration 描述的bean一般为一个配置类 */
@Configuration
public class SpringShiroConfig {
	/**
	 * @Bean一般用户描述方法,然后将方法的返回值 交给Spring管理,其中@Bean注解中的内容为Bean 对象的key。
	 * @return
	 */
	@Bean("securityManager")
	public SecurityManager newSecurityManager(ShiroUserRealm realm, CacheManager cacheManager,
			RememberMeManager rememberMeManager) {
		DefaultWebSecurityManager sm = new DefaultWebSecurityManager();
		sm.setRealm(realm);
		sm.setCacheManager(cacheManager);
		sm.setRememberMeManager(rememberMeManager);
		sm.setSessionManager(newSessionManager());
		return sm;// 不是java.lang包中的SecurityManager
	}

	@Bean("shiroFilterFactory")
	public ShiroFilterFactoryBean newShiroFilterFactoryBean(SecurityManager securityManager) {
		// 1.构建ShiroFilterFactoryBean对象(负责创建ShiroFilter工厂对象)
		ShiroFilterFactoryBean fBean = new ShiroFilterFactoryBean();
		// 2.设置安全管理器
		fBean.setSecurityManager(securityManager);
		// 3.设置登录页面对应的url(非认证用户要跳转到此url对应的页面)
		fBean.setLoginUrl("/doLoginUI.do");
		// 4.设置过滤规则(哪些允许匿名访问,哪些需要认证访问)
		Map<String, String> filterMap = new LinkedHashMap<String, String>();
		filterMap.put("/bower_components/**", "anon");
		filterMap.put("/build/**", "anon");
		filterMap.put("/dist/**", "anon");
		filterMap.put("/plugins/**", "anon");
		filterMap.put("/user/doLogin.do", "anon");
		filterMap.put("/doLogout.do", "logout");
		filterMap.put("/**", "user");
		fBean.setFilterChainDefinitionMap(filterMap);
		return fBean;
	}

	// ==========================
	// @Bean注解没有指定名字时,默认bean的名字为方法名
	@Bean("lifecycleBeanPostProcessor")
	public LifecycleBeanPostProcessor newLifecycleBeanPostProcessor() {
		return new LifecycleBeanPostProcessor();
	}

	@DependsOn("lifecycleBeanPostProcessor")
	@Bean
	public DefaultAdvisorAutoProxyCreator DefaultAdvisorAutoProxyCreator() {
		return new DefaultAdvisorAutoProxyCreator();
	}

	@Bean
	public AuthorizationAttributeSourceAdvisor newAuthorizationAdvisor(SecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
		advisor.setSecurityManager(securityManager);
		return advisor;
	}

	// 配置缓存管理器(可以缓存用户的权限信息)
	@Bean
	public MemoryConstrainedCacheManager newCacheManager() {
		return new MemoryConstrainedCacheManager();
	}

	// 配置记住我
	@Bean
	public CookieRememberMeManager newCookieManager() {
		CookieRememberMeManager cookieManager = new CookieRememberMeManager();
		SimpleCookie cookie = new SimpleCookie("rememberMe");
		cookie.setMaxAge(24 * 7 * 60 * 60);
		cookieManager.setCookie(cookie);
		return cookieManager;
	}

	// 配置session管理器
	public DefaultWebSessionManager newSessionManager() {
		DefaultWebSessionManager sManager = new DefaultWebSessionManager();
		sManager.setGlobalSessionTimeout(21600000);
		sManager.setDeleteInvalidSessions(true);
		sManager.setSessionValidationSchedulerEnabled(true);
		return sManager;
	}
}
package com.db.common.config;
import javax.servlet.FilterRegistration.Dynamic;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;

import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

//替换web.xml (参考官网实现)
public class AppWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
	//其中前端控制器的配置是在父类的onStart方法实现的。
	@Override
	public void onStartup(ServletContext servletContext) throws ServletException {
		registerFilter(servletContext);
		super.onStartup(servletContext);
	}
	private void registerFilter(ServletContext servletContext) {
		Dynamic d = servletContext.addFilter("shiroFilter",
		DelegatingFilterProxy.class);
		d.setInitParameter("targetBeanName","shiroFilterFactory");
		d.addMappingForUrlPatterns(null,true,"/*");
	}
	/**
          * 配置@Service,@Repository
     */
	@Override
	protected Class<?>[] getRootConfigClasses() {
		return new Class[] {SpringRespositoryConfig.class,SpringServiceConfig.class};
	}
	/**加载spring mvc配置*/
	@Override
	protected Class<?>[] getServletConfigClasses() {
		return new Class[] {SpringWebConfig.class} ;
	}
	/**定义映射路径(spring mvc要处理哪些url)*/
	@Override
	protected String[] getServletMappings() {
		System.out.println("getServletMappings");
		return new String[] {"/"};
	}

}

 

<think>好的,我现在需要帮助用户了解Apache Shiro使用方法和示例代码。根据用户提供的引用内容,我需要整理出一个清晰的步骤指南,并确保符合系统级指令的要求。首先,用户要求使用中文回答,结构清晰,并且包含相关问题。同时,要注意行内数学表达式用$...$,不过这里可能涉及的不多,但需要检查是否有需要的地方。另外,要正确引用提供的引用内容,并在末尾添加引用标识。 首先,我需要回顾用户提供的引用内容。引用[1]提到了配置Shiro、创建Realm和用户登录的步骤。引用[2]是示例代码的链接,引用[3]则补充了SpringBoot集成Shiro的依赖配置和配置步骤。用户的需求是了解Shiro使用方法或教程,以及示例代码。 接下来,我需要将这些信息组织成结构化的步骤。可能分为几个部分:环境配置、创建Realm、配置Shiro、用户登录认证、权限控制、会话管理和示例代码参考。每个部分需要结合引用内容,并适当添加代码示例,比如如何添加依赖,如何编写Realm类,如何配置Shiro的安全管理器等。 需要注意,用户提供的引用中有提到添加依赖的部分,这里需要正确引用引用[3]中的内容,例如Maven依赖的代码块。同时,在配置Shiro的部分,引用[1]和引用[3]都有提到,需要整合这两部分的信息,说明配置的步骤,比如创建ShiroConfig类,配置SecurityManager和ShiroFilterFactoryBean。 在用户登录认证部分,引用[1]提到使用Shiro的Subject进行登录,需要展示如何获取Subject实例,并调用login方法。同时,需要处理可能的异常情况,比如UnknownAccountException和IncorrectCredentialsException。 权限控制部分,可以提到Shiro的注解,如@RequiresPermissions,以及如何在代码中进行权限校验,这里需要引用相关的示例,但用户提供的引用中没有详细代码,可能需要简要说明。 会话管理部分,可以说明如何获取会话并设置属性,这部分引用中没有详细提到,但属于Shiro的常见用法,可以适当补充。 最后,示例代码参考部分需要引用用户提供的链接,即引用[2],并提示用户查看具体示例。 在生成相关问题的时候,要考虑用户可能进一步想知道的内容,比如集成SpringBoot的步骤、自定义Realm的实现、异常处理、权限控制方法、会话管理以及性能优化等。确保每个问题都覆盖用户可能感兴趣的方面。 现在需要检查是否符合所有系统级指令:使用正确的LaTeX格式(如果有数学表达式的话,但当前内容可能不需要),结构清晰,引用正确,生成相关问题,使用中文回答。此外,确保代码块正确使用三个反引号,并标明语言类型,如java或xml。 可能需要调整的地方包括正确引用每个步骤对应的引用来源,例如在添加依赖时引用[3],在配置Shiro时引用[1]和[3],在示例代码部分引用[2]。同时,注意引用标识的位置,应在相关段落末尾自然添加,如配置Shiro的步骤后添加[^1][^3]。 最后,确保回答中没有使用Markdown格式,除了代码块外,其他部分保持自然的中文叙述。检查所有引用是否正确对应,代码示例是否准确,并且相关问题是否覆盖了用户可能的需求。</think>### Apache Shiro 使用教程 Apache Shiro 是一个功能强大的安全框架,用于身份认证、权限控制和会话管理。以下是其核心使用方法: --- #### **1. 环境配置(SpringBoot集成)** 在 `pom.xml` 中添加 Shiro 和 Spring Boot 依赖: ```xml <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.8.0</version> </dependency> ``` 通过此配置可快速集成 Shiro 到 Spring Boot 项目中[^3]。 --- #### **2. 创建自定义 Realm** Realm 是 Shiro 的核心组件,用于连接安全数据(如数据库)与权限配置。需继承 `AuthorizingRealm` 并实现以下方法: ```java public class CustomRealm extends AuthorizingRealm { // 权限校验 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.addRole("admin"); // 添加角色 info.addStringPermission("user:read"); // 添加权限 return info; } // 身份认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) { String username = (String) token.getPrincipal(); if (!"admin".equals(username)) { throw new UnknownAccountException("用户不存在"); } return new SimpleAuthenticationInfo(username, "123456", getName()); } } ``` --- #### **3. 配置 Shiro 安全管理器** 在 Spring Boot 中通过 `ShiroFilterFactoryBean` 配置过滤规则: ```java @Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); factoryBean.setSecurityManager(securityManager); Map<String, String> filterMap = new LinkedHashMap<>(); filterMap.put("/login", "anon"); // 匿名访问 filterMap.put("/**", "authc"); // 需要认证 factoryBean.setFilterChainDefinitionMap(filterMap); return factoryBean; } @Bean public SecurityManager securityManager(Realm realm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(realm); return securityManager; } } ``` 此配置定义 URL 的访问权限[^3]。 --- #### **4. 用户登录认证** 在控制器中调用 Shiro 的 `Subject` 进行登录: ```java @PostMapping("/login") public String login(String username, String password) { Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username, password); try { subject.login(token); // 触发 Realm 的认证逻辑 return "登录成功"; } catch (UnknownAccountException | IncorrectCredentialsException e) { return "用户名或密码错误"; } } ``` --- #### **5. 权限控制** 通过注解或代码校验权限: ```java @RequiresPermissions("user:delete") // 需要 user:delete 权限 @GetMapping("/deleteUser") public String deleteUser() { return "删除用户成功"; } ``` --- #### **6. 会话管理** Shiro 提供统一的会话 API: ```java Subject subject = SecurityUtils.getSubject(); Session session = subject.getSession(); session.setAttribute("key", "value"); // 存储会话数据 ``` --- #### **7. 示例代码参考** 完整示例代码可参考:[Spring Boot 集成 Shiro 示例](https://gitee.com/itwenke/spring-boot-demo/tree/master/shiro)[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值