shiro 权限校验

applicationContext 中配置 

<!-- Shiro配置 -->
    
    <!-- 用户授权信息Cache:缓存控制器,来管理如用户、角色、权限等的缓存的;
  	 		因为这些数据基本上很少去改变,放到缓存中后可以提高访问的性能  --> 
    <bean id="memoryConstrainedCacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />
   
    <!-- 继承自AuthorizingRealm的自定义Realm,即指定Shiro验证的类 -->  
    <bean id="myRealm" class="com.lanou.shiro.MyShiroRealm">
    		<!-- 把realm对象添加到shiro的缓存中 -->
    	 	<property name="cacheManager" ref="memoryConstrainedCacheManager" /> 
    </bean> 
  
    <!-- 这里主要是设置自定义的单Realm应用,若有多个Realm,可使用'realms'属性代替
    		securityManager相当于SpringMVC中的DispatcherServlet,所有的校验工作都先进入它,
    		由它指派具体的校验realm
     -->  
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
        <!-- 把自定义的realm注入到SecurityManager中:
        	     把realm对象交由SercurityManager进行管理
         -->
        <property name="realm" ref="myRealm"/>  
        <!-- 配置多个realm -->
<!--         <property name="realms">  
       	 	<list>  
            		<ref bean="realm1"/>  
           	 	<ref bean="realm2"/>  
        		</list>  
   	 	</property>  --> 
    </bean>  
  
    <!-- Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的自定义过滤器的执行 -->  
    <!-- Web应用中,Shiro可控制Web请求必须经过Shiro主过滤器进行拦截,Shiro对基于Spring的Web应用提供了完美的支持 -->  
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
        <!-- Shiro的核心安全接口,这个属性是必须的 -->  
        <property name="securityManager" ref="securityManager"/>  
        <!-- 要求登录时的链接(可根据项目的URL进行替换),非必须的属性,默认会自动寻找webapp根目录下的"/login.jsp"页面 -->  
        <property name="loginUrl" value="/admin/login.jsp"/>  
        <!-- 登录成功后要跳转的连接(我们这里该属性用不到,因为登录成功后的处理逻辑在login.js中硬编码为index.jsp了) -->  
        <!-- <property name="successUrl" value="/admin/index.jsp"/> -->  
        <!-- 用户访问未对其授权的资源时,所显示的视图 -->  
        <property name="unauthorizedUrl" value="/admin/no-perm.jsp"/>  
        <!-- Shiro约束配置,即过滤链的定义 -->  
        <!-- 下面value值的第一个'/'代表的路径是相对于HttpServletRequest.getContextPath() -->  
        <!-- anon:放行,不进行校验 -->  
        <!-- authc:该过滤器下的页面必须验证后才能访问,它是Shiro内置的一个拦截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter -->  
        <property name="filterChainDefinitions">  
            <value>  
                <!-- 登录页面和错误不需要验证 -->  
            	/admin/login.jsp = anon
            	/admin/no-perm.jsp = anon
            	<!-- 需要验证 -->
导shiro相关jar包或者在maven 中注入依赖 
<!-- Shiro 安全校验框架 -->
		<!-- Spring 整合Shiro需要的依赖 -->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-core</artifactId>
			<version>1.2.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-web</artifactId>
			<version>1.2.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-ehcache</artifactId>
			<version>1.2.1</version>
		</dependency>



<!-- 需要放行的地址 -->
/admin/index.jsp = authc /admin/system-menu-list.jsp = authc,perms["system-menu-list"] /admin/system-role-list.jsp = authc,perms["system-role-list"] 等等等等 <!-- 需要验证具有role_001角色的用户可以访问,多用于跳转页面 可以配置多个,要用英文双引号扩起来用英文逗号分隔,例如roles["role_001,role_002"] --> <!-- /user/toImportUsers.do = authc,roles[role_001] /ztree/toZtree.do = authc,roles["role_001,role_002"] 需要验证具有role_001角色的selUserInfo权限的用户可以访问 ,多用于页面中某个请求 /user/selUserInfo.do = authc,perms[role_001:selUserInfo] 需要验证具有role_001角色的selUserInfo权限的用户可以访问 ,多用于页面中某个请求 /user/importUsers.do = authc,perms["role_001:add:,role_002:modify"] --> <!-- 不在被校验的url全部放行 --> /** = anon </value> </property> </bean> <!-- 管理shiroBean的生命周期 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!-- 权限shiro配置 结束 -->


在 web.xml 中 添加  shiro 过滤器配置 

<!-- shiro过滤器配置一定要写到DispatcherServlet之前 -->
	<filter>
		<!-- 注意DelegatingFilterProxy是一个代理类:
			web.xml中的filter-name必须和applicationContext.xml中配置的filter的id一致 -->
		<filter-name>shiroFilter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
		<init-param>
			<!-- 交由Spring管理Shiro对象的创建和销毁 -->
			<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>
---------------------神秘的分割线-------------------------------------------------------

controller 中加一个shiro 类

package com.lanou.shiro;

import java.util.ArrayList;
import java.util.List;


import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
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.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.springframework.beans.factory.annotation.Autowired;

import com.lanou.domain.Menu;
import com.lanou.domain.User;
import com.lanou.service.MenuService;
import com.lanou.service.UserService;


/**
 * 自定义Shiro校验规则:继承AuthorizingRealm
 * 
 * 
 */
public class MyShiroRealm extends AuthorizingRealm {
	@Autowired
	private MenuService menuService;
    @Autowired
   	private UserService userService;
    
    /**
	 * 权限校验:Authorization授权 为当前登录的Subject授予角色和权限 该方法在为需授权资源被访问时调用
	 * Principal是Subject的标识,一般情况下是唯一标识,比如用户名。
	 */  
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { 
		System.err.println("----验证当前登录用户拥有的权限或角色----");
		// 获取当前登录的用户名
    		String currentUsername = (String)super.getAvailablePrincipal(principals);  
		// 角色列表
    		List<String> roleList = new ArrayList<String>(); 
		// 权限列表
    		List<String> permissionList = new ArrayList<String>();  
		// 从数据库中获取当前登录用户拥有的所有菜单
    		List<Menu> menus = menuService.getByUsername(currentUsername);  
    		if(menus != null && menus.size() > 0){  
    			for(Menu menu : menus){
    				permissionList.add(menu.getUrlkey());
    			}
    		}  
		// 为当前用户设置角色和权限
		// 把校验信息封装到SimpleAuthorizationInfo对象中
    		SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();  
    		simpleAuthorInfo.addRoles(roleList);  
    		simpleAuthorInfo.addStringPermissions(permissionList);  
    		return simpleAuthorInfo;  
    }  
  
      
    /**
	 * 登录校验:Authentication身份认证 验证当前登录的Subject
	 * 该方法在LoginController的login()方法执行Subject.login()时被调用 进行身份认证的目的:
校验了3次 登录 一次 权限检验中一次 
	 * 1.一定程度上防止非法登录 2.把通过身份认证的用户信息封装到AuthenticationInfo对象中,
	 * 从而把已认证的用户交由SecurityManager进行管理 在logout之前不再对该用户的后续请求进行身份校验
	 * 
	 */  
    @Override  
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {  
		// 获取基于用户名和密码的令牌
		// 参数中的authcToken是从LoginController里面currentUser.login(token)传过来的
        UsernamePasswordToken token = (UsernamePasswordToken)authcToken;  
		System.err.println(
				"验证当前Subject获取到的token为:" + ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE));
		// 通过token.getUsername():获取登录的用户名
        User user = userService.getUserByName(token.getUsername());
        System.err.println("principal:" + token.getPrincipal());
        if(user != null){  
        		//this.getName():org.apache.shiro.realm.CachingRealm.getName()
			// 把通过身份校验的用户信息封装到AuthenticationInfo对象中 封装到缓存中 浏览器退出之前 ,可以不用重新登录 
			// 在logout之前不再对该用户的后续请求进行身份校验
        		AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(), 
        				this.getName());  
        		return authcInfo;  
        }  
        return null;  
    }  

}

在登录的 时候 进行 shiro 判断 

shiro 判断 1.先检验 用户身份 

 2.shiro 中再次 调用 user.getUsername 和user.password 再次检验 避免 非法登录










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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值