Spring+Shiro 配置

本文介绍如何将Apache Shiro与Spring框架集成,实现Web应用的权限管理和用户认证。主要内容包括配置web.xml和shiro.xml,自定义Realm从数据库读取用户信息,以及MD5加密密码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需要的jar包

spring的jar包和shiro的jar包
在这里插入图片描述

配置web.xml

<!-- shiro配置文件 -->
	<context-param>
	    <param-name>contextConfigLocation</param-name>
	    <param-value>classpath:shiro.xml</param-value>
	</context-param>
	<listener>
	    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<!-- SpringMVC的配置文件 -->
	<servlet>
	    <servlet-name>springDispatcherServlet</servlet-name>
	    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	    <init-param>
	        <param-name>contextConfigLocation</param-name>
	        <param-value>classpath:springmvc.xml</param-value>
	    </init-param>
	    <load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
	    <servlet-name>springDispatcherServlet</servlet-name>
	    <url-pattern>/</url-pattern>
	</servlet-mapping>
  
  <!-- 添加shiro过滤器,用来拦截shiro请求 -->
<filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>
	    org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>
    <init-param>
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

配置shiro.xml

<!-- 1.配置 securityManager管理器-->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
	    <!-- 缓存管理器 -->
	    <property name="cacheManager" ref="cacheManager"/>
	    <!-- 配置session的管理方式 -->
	    <property name="realm" ref="shiroRealm"/>
	</bean>
	<!-- 2.配置缓存管理器,可以设置缓存 -->
	<!-- 2.1 添加ehcache的jar包和配置文件 -->
	<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
	    <!-- <property name="cacheManager" ref="ehCacheManager"/> -->
	    <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/> 
	</bean>
	<!-- 3.配置实现了realm接口的bean -->
	<bean id="shiroRealm" class="com.znsd.shiro.realms.ShiroRealm"></bean>
	
	<!-- 4.配置lifecycleBeanPostProcessor,可以自动调用配置在spring中的shrio对象生命周期方法。 -->
	<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
	
	<!-- 5.启用IOC容器中的shiro注解,但必须在配置 lifecycleBeanPostProcessor 后才会生效。-->
	<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
	          depends-on="lifecycleBeanPostProcessor"/>
	<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
	    <property name="securityManager" ref="securityManager"/>
	</bean>
	<!-- 
    6.配置shiroFilter过滤器相关的属性。
    6.1 id必须 和web.xml中配置的filter-name一致。
	-->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
	    <property name="securityManager" ref="securityManager"/>
	     <!-- 用户的登录页面 -->
	    <property name="loginUrl" value="/login"/>
	    <!-- 登录成功之后的页面 -->
	    <property name="successUrl" value="/admin/welcome"/>
	    <property name="unauthorizedUrl" value="/unauthorized"/>
	    <!-- 
	        配置哪些页面需要被保护,以及访问该页面所需要的权限。
	        anon: 表示可以匿名访问。
	        authc:表示需要登录之后才可以访问。
	        logout:注销当前用户 。
			roles:用户权限。
	    -->
	    <property name="filterChainDefinitions">
	        <value>
	            /login = anon
	            /index.jsp= anon
	            /** = authc
	        </value>
	    </property>
	</bean>

配置springmvc.xml

<context:component-scan base-package="com.znsd.shiro"></context:component-scan>

		<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/"></property>
		<property name="suffix" value=".jsp"></property>
		</bean>
		
		<mvc:annotation-driven></mvc:annotation-driven>
		<mvc:default-servlet-handler/>

身份验证的基本流程

添加一个登陆表单

<form action="login" method="post">
		<table>
			<tr>
				<td>用户名:</td>
				<td><input type="text" name="username" /></td>
			</tr>
			<tr>
				<td>密码:</td>
				<td><input type="password" name="userpass" /></td>
			</tr>
			<tr>
				<td></td>
				<td>
					<input type="submit" value="登录" />
					<input type="reset" value="重置" />
				</td>
			</tr>
		</table>
	</form>

服务器获取表单提交的信息,进行验证

@RequestMapping(value = "/login", method = RequestMethod.POST)
	public String index2(User user) {
		//获取当前的Subject
		Subject currentUser = SecurityUtils.getSubject();
		        
		// 测试当前用户是否已经被认证,即是否已经登录。
		if (!currentUser.isAuthenticated()) {
		// 把用户名和密码封装为UsernamePasswordToken对象
		UsernamePasswordToken token 
			= new UsernamePasswordToken(user.getUsername(), user.getUserpass());
		// 记住密码
		token.setRememberMe(true);
		try {
		// 执行登录
		currentUser.login(token); //实际上调用Realm中的doGetAuthenticationInfo方法
		} catch (AuthenticationException e) { // 其他异常,是其他异常的父类
		    e.printStackTrace();
		    System.out.println("用户不存在");
		}
		}
		return "login";
	}

自定义Realm,从数据库读取用户信息

public class ShiroRealm extends AuthorizingRealm{
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //①、把AuthenticationToken转换为UsernamePasswordToken。
		UsernamePasswordToken upToken = (UsernamePasswordToken) token;
		//②、从UsernamePasswordToken中获取username
		String username = upToken.getUsername();
		//③、调用数据库的方法,从数据库中查询username对应的记录。
		ShiroService service=new ShiroService();
		User user=service.service(username);
		
		//④、若用户不存在,则可以跑出UnknownAccountException异常。
		if(user == null) {
			throw new UnknownAccountException("用户不存在.");
		}
		//⑤、根据用户信息的情况,决定是否需要抛出其它AuthenticationException异常。
		if(user.isLocked()) {
			throw new LockedAccountException("用户被锁定");
		}
		//⑥、根据用户的情况,来构建AuthenticationInfo对象并返回。
		AuthenticationInfo info = new SimpleAuthenticationInfo(user.getUsername(), user.getUserpass(), this.getName());
		return info;
	}
}

MD5加密

<!-- 添加自定义的Relm规则 -->
<bean id="shiroRealm" class="com.znsd.shiro.relms.ShiroRealm">
    <property name="credentialsMatcher">
    <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
    <!-- 指定使用MD5加密方式加密前台密码 -->
    <property name="hashAlgorithmName" value="MD5" />
    <!-- 指定使用MD5加密的次数 -->
    <property name="hashIterations" value="10" />
    </bean>
    </property>
</bean>
//生成加密的盐值
ByteSource salt = ByteSource.Util.bytes("www.znsd.com");
//这里的密码要是数据库中加密之后的密码。
AuthenticationInfo info = new SimpleAuthenticationInfo(user.getUsername(), user.getUserpass(), salt, getName());

SimpleHash通过构造函数进行加密,提供了多种方法的重载

public SimpleHash(String algorithmName, Object source, Object salt, int hashIterations)

参数说明:
algorithmName:采用什么方式加密。MD5,SHA-1等。
source:要加密的字符串。
salt:用来加密的盐值。
hashIterations:加密的次数

//生成加密的盐值
ByteSource salt = ByteSource.Util.bytes("www.znsd.com");
//进行MD5加密
SimpleHash sh = new SimpleHash("MD5", "123123", salt, 10);
System.out.println(sh);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值