shiro的理解

shiro  ,三大块。

前期准备ehcache.xml,以及mvc以及shiro和shiro-spring等等的jar包,

然后开始配置

第一块 web.xmlddddddd

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  
  
  	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>
	
	<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>
		<!-- <init-param>
			<param-name>targetBeanName</param-name>
			<param-value>shiroFilter</param-value>
		</init-param> -->
	</filter>

	<filter-mapping>
		<filter-name>shiroFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<listener> //配置监听
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	
	<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>
第二块 shiro-servlet.xml  (不同的人可以起不同的名字,他的位置在web-inf下面,)

<?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="com.zzsxt.lee.web.shiro"></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>
第三块:applicationContext.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">

	<!-- ========================================================= Shiro Core 
		Components - Not Spring Specific ========================================================= -->
	<!-- 1.配置securityManager:安全管理器 -->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<!-- 缓存管理器 -->
		<property name="cacheManager" ref="cacheManager" />
		<!-- !!!!!!!realm -->
		<property name="realm" ref="jdbcRealm" />
	</bean>

	<!-- 2.cacheManager:配置缓存管理器 为了使项目更高效的运行 弊端:如果用户的账号和密码放在缓存中,无论在登录页面舒服什么账号和密码都可以直接登录 
		所以一旦账号和密码存入缓存中了,需要直接退出(logout) -->
	<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
		<!-- 两种配置缓存的方式 第一种:配置多个缓存所需要的配置信息 -->
		<!-- Set a net.sf.ehcache.CacheManager instance here if you already have 
			one. If not, a new one will be creaed with a default config: <property name="cacheManager" 
			ref="ehCacheManager"/> -->
		<!-- 第二种:配置单个缓存,直接以属性的形式配置进cacheManager中 -->
		<!-- If you don't have a pre-built net.sf.ehcache.CacheManager instance 
			to inject, but you want a specific Ehcache configuration to be used, specify 
			that here. If you don't, a default will be used.: <property name="cacheManagerConfigFile" 
			value="classpath:some/path/to/ehcache.xml"/> -->
		<!-- 配置缓存:从hibernate源码中找到ehcache.xml copy到项目的根目录 -->
		<property name="cacheManagerConfigFile" value="classpath:ehcache.xml" />
	</bean>

	<!-- 3. m,如果没有自定义,可以使用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的路径 -->
	<!-- Used by the SecurityManager to access security data (users, roles, 
		etc). Many other realm implementations can be used too (PropertiesRealm, 
		LdapRealm, etc. -->
	<bean id="jdbcRealm" class="com.zzsxt.lee.web.shiro.MyRealm3">
		<!-- 如果需要使用加密政策 -->
		<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>

	<!-- ========================================================= Shiro Spring-specific 
		integration ========================================================= -->
	<!-- Post processor that automatically invokes init() and destroy() methods 
		for Spring-configured Shiro objects so you don't have to 1) specify an init-method 
		and destroy-method attributes for every bean definition and 2) even know 
		which Shiro objects require these methods to be called. -->
	<!-- 4.配置lifecycleBeanPostProcessor:生命周期 把shiro的生命周期托管给spring IOC容器进行处理 
		shiro的init方法和destroy方法都由spring来进行管理调用 -->
	<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

	<!-- Enable Shiro Annotations for Spring-configured beans. Only run after 
		the lifecycleBeanProcessor has run: -->
	<!-- 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的路径匹配顺序:遵循第一次匹配优先顺序(在没有通配符的情况下) 如果和通配符连用,则遵循覆盖原则 
			logout:退出登录
			roles:判断该用户是否有该角色
					如果在roles标签中的[]里配置了两个角色,这两个角色是并集的关系
		-->
		<property name="filterChainDefinitions">
			<value>
				/login.jsp = anon
				/shiro/login = anon
				/logout = logout
				/shiro/test = anon
				<!-- /user.jsp = roles[user]
				/admin.jsp = roles[user,admin] -->
				/** = authc
			</value>
		</property>
	</bean>
	
	<bean id="loginService" class="com.zzsxt.lee.web.shiro.service.LoginService"></bean>

</beans>

以上这些都是配置,下面是真正的代码

在applicationContext。xml里面的第6步,进行一些拦截,

/login.jsp = anon
/shiro/login = anon
这两个是对外开放的, 即 不需要任何权限就可以看到,也不会被拦截。

在controller层,需要对登录的用户进行判断,---会到appliactionContext.xml里面找

第3步 "jdbcRealm",对密码进行加密,这里,最好用自己定义的realm,如下

package com.zzsxt.lee.web.shiro;

import java.util.HashSet;
import java.util.Set;
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.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
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.apache.shiro.util.ByteSource;

import com.zzsxt.lee.web.shiro.model.User;

/**
 * @description shiro��֤����Ȩ shiro���հ汾 1.�̳�org.apache.shiro.realm.AuthorizingRealm
 *              2.��д�������� ��֤doGetAuthenticationInfo() ��ȨdoGetAuthorizationInfo()
 *        ʵ����Ȩ��
 *        	ͨ�������ļ�(applicationContext.xml)�ҵ�bean��idΪfilterChainDefinitions
 *        		���shiro��Ȩ�ޱ�ǩ
 *       	ͨ��jstl��ǩ����ʵ��shiroȨ���ж�
 * @author Seven Lee
 *
 */
public class MyRealm3 extends AuthorizingRealm {

	/**
	 * @description ��֤
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// 1.从controller层传来的token,将其强转,
		UsernamePasswordToken uptoken = (UsernamePasswordToken) token;
		// 2.ͨ通过token获取用户名
		String username = uptoken.getUsername();
		// 3.
		User user = new User("zhangsan", "2a0d136ceacafe198ea64ac09daaf1b6", "male");
		// 4.�ж��Ƿ���Ҫ�׳��쳣
		if (username.equals(user.getUsername())) {

		} else {
			throw new UnknownAccountException("�û���������");
		}

		// 5.�����Լ��������ȡ�û���Ϣ������AuthenticationInfo����
		// principal:�û���Ϣ
		// ��username�����ߴ�����User����
		// credentials:����
		// SimpleAuthenticationInfo info = new
		// SimpleAuthenticationInfo(username, "123456", getName());
		// credentialsSalt:��ֵ
		ByteSource salt = ByteSource.Util.bytes(username);
		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, user.getPassword(), salt, getName());
		return info;
	}

	/**
	 * @description ��Ȩ
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection colletion) {
		/**
		 * PrincipalCollection:是从认证阶段返回的SimpleAuthenticationInfo对象
		 * 如果在认证阶段,返回是username,则授权阶段可以获取到username
		 * 如果在认证阶段,返回的是User对象,授权阶段可以获取该User对象
		 */
		// 1.ͨ通过PrincipalCollection获取username
		String username = (String) colletion.getPrimaryPrincipal();

		// 2.ͨ通过获取到username查询数据库,查看该user所对应的roles
		Set<String> roles = new HashSet<String>();
		// 3.ͨ通过username获取该角色下的权限
		Set<String> permissions = new HashSet<String>();
		roles.add("user");
		if("admin".equals(username)) {
			// 如果登陆者满足某种条件,则让其拥有admin权限,并且添加delete权限
			roles.add("admin");
			permissions.add("user:delete");
		}
		permissions.add("user:look");
		// 4.创建AuthorizationInfo对象
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		// 5.把角色信息添加AuthorizationInfo对象
		info.addRoles(roles);
		// 6.把权限信息添加到AuthorizationInfo对象
		info.addStringPermissions(permissions);
		// 7.返回SimpleAuthorizationInfo对象
		return info;
	}
}

上面第一个方法是对用户的登录认证,下一个方法是对用户的授权

完成之后,会回到controller,进行跳转页面,这时,用户已经拥有了自己应该拥有的权限,然后会有两种方法对用户的权限进行判断,

一个是在applicationcontext.xml的第六步,进行判断,

如:/user.jsp = roles[user],这是说明,user拥有看user.jsp 页面的权利

/admin.jsp = roles[user,admin] ,这是说明,用户需要有“user”和“admin”l两种身份才能访问
另一种实在页面加入shiro标签,然后进行判断
可以是这种简单的判断,(判断是否是某类用户,就可以看到某个链接或者按钮)
<shiro:hasRole name="admin">
  		<a href="admin.jsp">Admin Page</a>
  	</shiro:hasRole>
也可以是下面这种,不仅对用户进行判断,还要对其权限进行判断否则
<shiro:hasRole name="user">
  		<shiro:hasPermission name="user:look">
  			<a href="user.jsp">User Page</a>
  		</shiro:hasPermission>
  	</shiro:hasRole>

这些都是雏形,以后更新应用版



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值