# weasel-spring-shiro **Repository Path**: pickear/weasel-spring-shiro ## Basic Information - **Project Name**: weasel-spring-shiro - **Description**: shiro - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 9 - **Forks**: 8 - **Created**: 2015-09-25 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README

前言

shiro是一个类似于spring-security的安全框架。shiro的轻量,简单易用,丰富标签,丰富注解,可读性,可扩展性深深吸引了很多使用者。shiro可以无缝接入到普通项目,普通web项目和spring项目中。这个包是基于spring项目,对shiro常用的东西做了一些封装。shiro已经很通用,所以封装不一定适合所有的人,但该项目尽量在封装的基础上做得通用,让大部分的使用者都能引入到自己的项目中,也可以给使用者提供一些思路。


功能

        一 提供了简单的用户,角色,权限的概念。

        二 封装了用户登录,自动登录,退出登录,session共享,跨域session共享(变相单点登录)等功能。

        三 扩展了shiro判断角色,权限的filter,提供了两个用于判断多个角色或权限任意一个满足的判断。

        四 提供一些帮助类似,让用户可以很方便清理权限缓存和踢出用户。

        五 登录密码错误一定次数锁定用户(默认6次,锁定30分钟)。

        六 自动登录。

        七 防xss,csrf攻击,过滤敏感词。


依赖包

  该项目作为weasel-root下的一个子模块,依赖了weasel-root下的其他子模块,其中包括weasel-root,weasel-core,weasel-helper模块。因为这几个模块并没有放在maven的中央仓库中,所以用户需要先把这几个项目打个成jar放在自己本地的maven仓库下。weasel-root的所有模块源码可以在本人的git上找到。地址分别是:

weasel-root :http://git.oschina.net/pickear/weasel-root

weasel-core:http://git.oschina.net/pickear/weasel-core

weasel-helper:http://git.oschina.net/pickear/weasel-helper

用户在自己的web的pom.xml文件中添加以下依赖包:

      <groupId>com.weasel.root</groupId>
<artifactId>weasel-root</artifactId>
<version>1.0.0-RELEASE</version>

        

配置

下面介绍如何引进这个包在自己的项目中,如果去配置,怎么在自己的项目中集成shiro。

首先,在web.xml文件开头添加以下配置:

        <filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

        在项目中添加一个shiro的配置文件,比如在resources目录下,添加shiro文件夹,然后在文件夹里添加shiro-config.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.xsd">


<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/login" />
<property name="successUrl" value="/" />
<property name="unauthorizedUrl" value="/unauthorized" />
<property name="filters">
<map>
<entry key="anyRoles" value-ref="anyRolesAuthorizationFilter" />
<entry key="anyPerms" value-ref="anyPermissionsAuthorizationFilter" />
</map>
</property>
<property name="filterChainDefinitions">
<value>
   /login* = anon
   /resources/** = anon
/** = authc
</value>
</property>
</bean>

<import resource="classpath*:/shiro/shiro-context.xml"/>

</beans>

          我们看到,在这个文件中引入了一个叫shiro-context.xml的文件,这个文件就是在weasel-sping-shiro这个项目中定义的,这个项目中定义了很多shiro的必要配置。下面再对shiro-context.xml这个文件作讲解。

         在spring的配置文件中,添加如下几个配置:

        <import resource="classpath:shiro/shiro-config.xml" />
       <context:component-scan base-package="com.weasel.security" />

        在这里,shiro需要获取一些用户的信息,这样才能对用户做一些登录和权限的判断。所以,用户在自己的项目中,需要实现com.weasel.security.domain.user.UserService这个接口,并将实现类似的bean交给spring理解,因为在本项目的realm中会通过spring将这个bean注入给shiro。否则,启动就会报bean找不到的错误。当然,怎么实现这个接口,怎么去查表,就是用户自己决定的了。

这样,项目配置就完成了,项目就可以正常使用。当然,用户想做一些扩展也行。下面介绍对shiro缓存的一种扩展。

缓存

默认的情况下,shiro使用的是本地缓存,这三个缓存分别是用来缓存session和当前用户的,分别是:

com.weasel.security.shiro.cache.repository.impl.LocalCacheOperations

com.weasel.security.shiro.cache.repository.impl..LoginErrorLocalCacheServiceImpl

com.weasel.security.shiro.cache.repository.impl.UserSessionRelationLocalCacheServiceImpl

当然,用户也是可以提供自己的缓存方案,分别实现以下接口,并将这三个实现的bean交给spring管理(注意:如果项目是分布式的,请实现下面三个接口,让分布式项目共享下面三个接口的数据):

com.weasel.security.shiro.cache.repository.CacheRepository
com.weasel.security.shiro.cache.repository.LoginErrorCacheService

com.weasel.security.shiro.cache.repository.UserSessionRelationCacheService


帮助类

该包提供了ShiroAuthorizationHelper和ShiroSecurityHelper两个有用的帮助 类似

        清除当前用户授权信息:ShiroAuthorizationHelper.clearAuthorizationInfo();

        清除指定用户授权信息:ShiroAuthorizationHelper.clearAuthorizationInfo(username);

        清除session认证信息:ShiroAuthorizationHelper.clearAuthenticationInfo(sessionid);

        获得当前用户:ShiroSecurityHelper.getCurrentUser();

         获得当前用户名:ShiroSecurityHelper.getCurrentUsername();

         获得当前session:ShiroSecurityHelper.getSession();

         获得当前sessionid:ShiroSecurityHelper.getSessionId();

         通过用户名获得session:ShiroSecurityHelper.getSessionByUsername(username);   #不建议使用,用户量大时有性能问题,用户可以在自己应用中用户登录时将用户跟session关联,自己实现。

         踢出指定用户:ShiroSecurityHelper.kickOutUser(username);  


使用

用户只需要将SecurityServer注入到自己的项目中,就可以使用shiro。SecurityServer这个类提供了登录,退出,自动登录等功能。这个类的bean已经默认交给spring管理,所以用户在自己的项目中只需要注入,向spring要这个bean就可以。如用户需要登录,只需要调用login(User user, HttpServletRequest request, HttpServletResponse response)方法,注意,user的password是没有加密的。如用户需要退出,调用logout()方法。如用户需要自动登录,调用autoLogin(HttpServletRequest request, HttpServletResponse response)方法。注意,如果要自动登录,在登录页面的表单中,需要有一个name值"为rememberMe"的勾选控件,让用户选择是否自动登录。当用户提交登录表单时,这个值会传到后台。如果登录页面没有这个勾选控件,默认不开启自动登录。下面给出一个简单的例子:

import com.weasel.security.SecurityServer;
import com.weasel.security.domain.user.User;
import com.weasel.security.exception.UnAllowLoginException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

@Controller
public class HelloController {

	@Autowired
	private SecurityServer server;

	@RequestMapping(value = "/",method = GET)
	public String index(HttpServletRequest request,HttpServletResponse response){

		return "index";
	}

	/**
	 * @param user
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/login",method = POST)
	public String login(User user,HttpServletRequest request,HttpServletResponse response,Model model){

		try {
			/*//如果想只能同时一个浏览器登录某一用户,请用下面方法。
			server.login(user,true, request, response);*/
			server.login(user, request, response);
		}catch (UnAllowLoginException e){
			model.addAttribute("error",request.getAttribute("error"));
			return "error";
		}

		return "index";
	}

	@RequestMapping(value = {"/login"},method = GET)
	public String login(HttpServletRequest request,HttpServletResponse response){

		return "login";
	}

	@RequestMapping(value = "/logout",method = GET)
	public String logout(HttpServletRequest request,HttpServletResponse response){

		server.logout();

		return "index";

	}
}


自动登录

包中提供了一个AutoLoginInterceptor,用户可以在spring的配置文件中添加以下的配置,达到自动登录的目的:

 

   <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**/*"/>
            <bean class="com.weasel.security.interceptor.AutoLoginInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

判断权限扩展

该包中提供了两个判断权限的扩展filter,其中一个是用来判断任意一个角色的,另一个是判断任意一个权限的。使用如下:

        例如想http://www.xxx.com/aa.html这个链接有zhangsan或者lixi角色的用户都可以访问,那么可以配置成/aa.html=anyRoles["zhangsan","lixi"];

        如果想http://www.xxx.com/bb.html这个链接有delete或者save权限的用户可以访问,那么可以配置成/bb.html=anyPerms["delete","save"];

防xss,csrf攻击

包中提供了两个filter,分别是XssFilter和CsrfFilter。XssFilter用来防xss攻击,CsrfFilter用来防xss和csrf攻击。如果需要系统防xss攻击,在web.xml的shiroFilter后面添加XssFilter的配置:

	<filter>
		<filter-name>xssFilter</filter-name>
		<filter-class>com.weasel.security.escape.filter.XssFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>xssFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

同理,如果同时需要防xss和csrf,请在web.xml的shiroFilter后面添加CsrfFilter配置。当然,这两个filter到底是拦截什么内容,要不要拦截所有的请求,就要根据用户具体的业务决定了。

注意,防csrf的原理是通过给请求添加随机token,在服务端验证token来完成的,并且不验证GET请求。所以,请用户遵循GET请求不修改资源的原则。并且,用户在提交请求的时候,需要从session中拿到token并发回到服务端。例如页面要提交一个form表单来删除某条记录,需要在form表单中获取session中的"csrf_token"值,并随同表单发回到服务端。例如在form表单中添加以下input:

<input name="csrf_token" value="${sessionScope.csrf_token}" type="hidden"/>


过滤敏感词

包中提供了一个SensitiveWordFilter,用于过滤敏感词。用户可以在web.xml中shiroFilter后面添加SensitiveWordFilter来达到敏感词过滤的目的。请用户将敏感词写在lexicon.txt文件中,并放在classpath下。filter的配置以下:

	<filter>
		<filter-name>sensitiveWordFilter</filter-name>
		<filter-class>com.weasel.security.escape.filter.SensitiveWordFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>sensitiveWordFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

覆盖配置

该包中提供了一个用于配置shiro的session超时时间,登录错误次数锁定用户等配置信息,用户可以覆盖该文件进行更改配置。只需要用户在自己的classpath:/shiro目录下,创建一个叫security.properties的文件,根据自己的需求更改相应的配置信息,配置信息以下:

#域名
domain=
path=
##在cookie中rememberMe的名字
rememberMeCookieName=rememberMe
##自动登录最长有效时间(分钟)
rememberMeTime=604800
##在cookie中seccionid的名字
sessionIdCookieName=jsid
#session超时时间(毫秒)
globalSessionTimeout=1800000
#验证session有效性定时器时间间隔(毫秒)
sessionValidationInterval=1800000


#密码错误多少次后锁定用户的
lock.error.count=6
#锁定用户多长时间(分钟)
lock.user.time=30