Shiro验证登录的springmvc框架的demo

1.先建一个实体UserInfo(由浅入深的顺序):

public class UserInfo implements Serializable{
	
	private Long userId;

    private String userName;

    private Integer userAge;

    private String userAddress;

    private String userAccount;

    private String userPassword;
}

注意此处是省略了get/set方法

2.Controller层

@Controller
@RequestMapping("/shiro")
public class LoginController {
	@RequestMapping("/login")
	public String login(@RequestParam("username") String name,@RequestParam("password") String pass){
		Subject subject = SecurityUtils.getSubject();
		if(!subject.isAuthenticated()){
			UsernamePasswordToken token = new UsernamePasswordToken(name,pass);
			subject.login(token);//最终的login方法会被提交到realm中
		}
		//重定向到页面
		return "redirect:/list.jsp";
	}
}

3.自定义的realm认证方法:

从token里面获取用户数据

public class MyRealm2 extends AuthenticatingRealm{
	/**
	 * 认证方法
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// TODO Auto-generated method stub
		//先把authenticationToken强转为UserNamePasswordToken
		UsernamePasswordToken upToken = (UsernamePasswordToken)token;
		//通过usernamePasswordToken获取用户名
		String username= upToken.getUsername();
		//开始比对数据库
		UserInfo userInfo = new UserInfo(1L,"张三",22,"上海","zhangsan","zhangsan");
		//判断是否需要抛出异常
		if(username.equals(userInfo.getUserName())){
			
		}else{
			throw new UnknownAccountException("用户名不存在");
		}
		//根据自己的情况获取用户信息并返回AuthenticationInfo对象
		//principal:用户信息
		//传username或者整个user对象
		//credentials:密码
		ByteSource salt = ByteSource.Util.bytes(username);
		String password =  new SimpleHash("md5","zhangsan",salt,1024).toHex();

		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username,password,salt,getName());
		return info;
	}
	
}

注意:这个步骤:String password =  new SimpleHash("md5","zhangsan",salt,1024).toHex();是为了迎合配置文件里面对密码加密的,若配置文件没有配置加密密码,那么也不需要此步骤,否则会验证不通过

4.配置文件

4.1applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <!-- 配置securityManager 管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    	<!-- 缓存管理器 -->
    	<property name="cacheManager" ref="cacheManager"></property>
    	<!-- realm领域 -->
    	<property name="realm" ref="jdbcRealm"></property>
    </bean>
    <!-- cacheManager:配置缓存管理器 为了使项目更高的运行,弊端:如果用户的账号和密码放在了缓存中,无论在登录页面输入什么账号密码都可以登录,
    	所以,一旦账号和密码进入缓存了,就需要logout方法才能退出缓存了 -->
    <bean id ="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
		<!-- 两种配置缓存的方式 第一种:配置多个缓存所需要的配置信息 -->
		<!-- 第二种:配置单个缓存,直接以属性的形式配置进cacheManager中 -->
		<!-- 配置缓存:从hibernate源码中找到ehcache.xml copy到项目的根目录 -->
		<property name="cacheManagerConfigFile" value="classpath:ehcache.xml" /> 
    </bean>
    <!-- 3.配置自定义的Realm,如果没有自定义,可以使用shiro自带的默认Reaml(在真实开发环境中,不允许使用) Many other 
		realm implementations can be used too:其他很多的org.apache.shiro.realm.Realm的实现类也可以被使用 
		3.1.创建Java类,不允许叫Realm,实现org.apache.shiro.realm.Realm的接口 3.2.修改class的路径 -->
	<bean id="jdbcRealm" class="cn.jzh.shiro.MyRealm2">
		<!-- 如果需要使用加密政策 -->
		<property name="credentialsMatcher">
			<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
				<property name="hashAlgorithmName" value="MD5"></property><!-- 指定加密的方式:MD5 -->
				<property name="hashIterations" value="1024"></property><!-- 指定了加密的次数 -->
			</bean>
		</property>
	</bean>
    <!-- 4.配置lifecycleBeanPostProcessor:生命周期 把shiro的生命周期托管给spring IOC容器进行处理 
		shiro的init方法和destroy方法都由spring来进行管理调用 -->
	<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />	
	<!-- 5.配置org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator 
		开启shiro自己的注解 DefaultAdvisorAutoProxyCreator必须要配置在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.shiro的核心配置 6.1.配置shiroFilter:过滤器,进行过滤指定路径信息 第一种配置:shiro配置id为shiroFilter必须要和web.xml中<filter-name>一致 
		第二种配置: <filter> <init-param> <param-name>targetBeanName</param-name> <param-value>shiroFilter123</param-value> 
		</init-param> </filter> 通常情况下,第二种配置是不会被使用的 如果对不上 则抛出org.springframework.beans.factory.NoSuchBeanDefinitionException: 
		No bean named 'shiroFilter' is defined -->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="securityManager" ref="securityManager" />
		<!-- 登录的路径 -->
		<property name="loginUrl" value="/login.jsp" />
		<!-- 登录成功所需要跳转的路径,一般情况下由controller进行配置,所以这一个配置信息可以不要 -->
		<property name="successUrl" value="/index.jsp" />
		<!-- 没有权限的页面 -->
		<property name="unauthorizedUrl" value="/unauthorized.jsp" />
		<!-- 配置权限信息: 
			anon:允许匿名访问,也就是这个路径不需要进行认证(登录) 
			authc:必须认证(登录)后才可以访问的路径 通配符: 
			*:/test/* 在test的下一级目录/test/a允许访问 /test/a/a/不允许访问 **:/test/** 所有的子目录都可以访问 
			shiro的路径匹配顺序:遵循第一次匹配优先顺序(在没有通配符的情况下) 如果和通配符连用,则遵循覆盖原则 -->
		<property name="filterChainDefinitions">
			<value>
				/login.jsp = anon
				/shiro/login = anon
				/** = authc
			</value>
		</property>
	</bean>
</beans>

4.2缓存配置文件ehcache.xml

<ehcache>
	<diskStore path="java.io.tmpdir" />
	<cache name="authorizationCache" eternal="false"
		timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false"
		statistics="true">
	</cache>

	<cache name="authenticationCache" eternal="false"
		timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false"
		statistics="true">
	</cache>

	<cache name="shiro-activeSessionCache" eternal="false"
		timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false"
		statistics="true">
	</cache>

	<defaultCache maxElementsInMemory="10000" eternal="false"
		timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" />

	<cache name="sampleCache1" maxElementsInMemory="10000" eternal="false"
		timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true" />
		
	<cache name="sampleCache2" maxElementsInMemory="1000" eternal="true"
		timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="false" />
</ehcache>

4.3shiro-server.xml的核心配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

	<context:component-scan base-package="cn.jzh"></context:component-scan>
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>
	<mvc:annotation-driven></mvc:annotation-driven>
	<!-- 处理静态资源 让静态资源可以直接访问-->
	<mvc:default-servlet-handler/>
</beans>

4.4页面的web.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>shiro_demo_spring_2</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <context-param>
  	<param-name>contextConfigLocation</param-name>
  	<param-value>classpath*:applicationContext.xml</param-value>
  </context-param>
  <listener>
  	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <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>
  <servlet>
  	<servlet-name>shiro</servlet-name>
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  	<load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
  	<servlet-name>shiro</servlet-name>
  	<url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

5.页面文件

login.jsp

<body>
    <h1>Login Page</h1>
    <form action="shiro/login" method="get">
    	用户名:<input type="text" name="username"><br>
    	密&nbsp;&nbsp;&nbsp;码:<input type="password" name="password"><br>
    	<input type="submit" value="提交">
    </form>
  </body>

猜你喜欢

转载自blog.csdn.net/u012060033/article/details/88294153
今日推荐