spring boot整合shiromvc + shiro 整合,shiro注解无效什么鬼

shiro-入门,快速与springmvc整合,全注解,最简单让项目运行起来
笔记:springboot、springmvc全注解入门整合shiro
该示例:大概功能如下:
由于角色可以自由创建,拥有权限分配的功能的帐号,可以把自身的权限分配给创建的角色。所以本人只想到了,使用请求地址来控制每一个权限。
整合开始:
1.添加shiroFilter过滤器
在能替代web.xml的配置类中添加过滤器
* 用注解方式,类里面配置,完全取代 web.xml中的配置
@HandlesTypes(WebApplicationInitializer.class)
public class WebXml implements ServletContextInitializer {
Logger logger = LoggerFactory.getLogger(getClass());
public void onStartup(ServletContext servletContext) throws ServletException {
(&加载shiro过滤器,与spring集成&);
* 找名字为shiroFilter(filter-name)的bean 并把所有Filter的操作委托给它。然后将ShiroFilter
* 配置到spring容器即可
Dynamic shiroFilter = servletContext.addFilter(&shiroFilter&, DelegatingFilterProxy.class);
shiroFilter.setInitParameter(&argetFilterLifecycl&, &true&);
shiroFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, &/*&);
shiroFilter.setAsyncSupported(true);
2.配置WebMvcConfigurer
下面的类中有点多,但是指需要添加与shiro先关的几个bean就成了。
之前的是在项目中配置好的
public class WebConfig extends WebMvcConfigurerAdapter {
Logger logger = LoggerFactory.getLogger(getClass());
public ServletContextInitializer getMyFilter() {
(&注册web.xml中对应的配置都可以在这里类里面编写-----------&);
return new WebXml();
* 添加全局异常处理器 1:这里好像是不用屏蔽 springmvc自动注册的全局异常处理器 2:编写自定义处理器 实现
* HandlerExceptionResolver 3:在这里加载
public HandlerExceptionResolver getHandlerExceptionResolver() {
(&加载自定义异常处理器&);
return new ExceptionResolverCustom();
public void addInterceptors(InterceptorRegistry registry) {
(&自定义拦截器在这里增加&);
registry.addInterceptor(new LoginInterceptor());
super.addInterceptors(registry);
public EmbeddedServletContainerCustomizer containerCustomizer() {
(&加载错误页面相关处理,spring boot中可以对根据对应的状态码,比如404,等添加指定的页面&);
return new MyCustomizer();
public SessionIdGenerator sessionIdGenerator() {
JavaUuidSessionIdGenerator jusg = new JavaUuidSessionIdGenerator();
public EnterpriseCacheSessionDAO sessionDao() {
EnterpriseCacheSessionDAO ecd = new EnterpriseCacheSessionDAO();
ecd.setSessionIdGenerator(this.sessionIdGenerator());
ecd.setCacheManager(this.shiroCacheManager());
private EhCacheManager ec
public EhCacheManager shiroCacheManager() {
if(ec == null) {
ec = new EhCacheManager();
ec.setCacheManagerConfigFile(&classpath:ehcache-shiro.xml&);
public SessionManager sessionManager() {
DefaultWebSessionManager dwsm = new DefaultWebSessionManager();
dwsm.setGlobalSessionTimeout(1800000);
dwsm.setDeleteInvalidSessions(true);
dwsm.setSessionDAO(this.sessionDao());
public SecurityManager securityManager() {
UserRealm singleRealm = new UserRealm();
singleRealm.setAuthorizationCachingEnabled(true);
DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager(singleRealm);
dwsm.setSessionManager(this.sessionManager());
public MethodInvokingFactoryBean methodInvokingFactoryBean() {
MethodInvokingFactoryBean mifb = new MethodInvokingFactoryBean();
mifb.setStaticMethod(&org.apache.shiro.SecurityUtils.setSecurityManager&);
mifb.setArguments(new Object[] {this.securityManager()});
@Bean(name=&shiroFilter&)
public ShiroFilterFactoryBean shiroFilterFactoryBean () {
ShiroFilterFactoryBean sffb = new ShiroFilterFactoryBean();
sffb.setSecurityManager(this.securityManager());
sffb.setLoginUrl(&/login.html&);
sffb.setUnauthorizedUrl(&/unAuthc.html&);
Map&String, Filter& filters = new HashMap&&();
filters.put(&sysUser&, new SysUserFilter());
sffb.setFilters(filters);
Map&String, String& filterChainDefinitionMap = new LinkedHashMap&String, String&();
filterChainDefinitionMap.put(&/login.html&, &anon&);
filterChainDefinitionMap.put(&/system/login/login&, &anon&);
filterChainDefinitionMap.put(&/system/login/logOut&, &anon&);
filterChainDefinitionMap.put(&/errorCustom.html&, &anon&);
filterChainDefinitionMap.put(&/unAuthc.html&, &anon&);
filterChainDefinitionMap.put(&/views/app.js&, &anon&);
filterChainDefinitionMap.put(&/js/**&, &anon&);
filterChainDefinitionMap.put(&/&, &anon&);
filterChainDefinitionMap.put(&/images/**&, &anon&);
filterChainDefinitionMap.put(&/imag/**&, &anon&);
filterChainDefinitionMap.put(&/wxMessagePic/*&, &anon&);
filterChainDefinitionMap.put(&/css/**&, &anon&);
filterChainDefinitionMap.put(&/**&, &sysUser&);
public LifecycleBeanPostProcessor LifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
3.编写自定义UserRealm
获取spring容器思路:
import org.apache.shiro.realm.AuthorizingR
public class UserRealm extends AuthorizingRealm {
* 获取授权信息,用户所拥有的角色和权限
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
ShiroPrincipal shiroPrincipal = (ShiroPrincipal) principals.getPrimaryPrincipal();
Set&String& psIds = null;
if (shiroPrincipal.isAuthorized()) {
psIds = shiroPrincipal.getAuthorities();
ISecurityService iss = Config.webApplicationContext.getBean(ISecurityService.class);
psIds = iss.findByUsername(shiroPrincipal.getUsername());
shiroPrincipal.setAuthorized(true);
} catch (Exception e) {
e.printStackTrace();
SimpleAuthorizationInfo si = new SimpleAuthorizationInfo();
si.setStringPermissions(psIds);
* 获取身份验证相关信
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
String password = new String((char[]) token.getCredentials());
ShiroPrincipal principal = new ShiroPrincipal(username);
return new SimpleAuthenticationInfo(principal, password, this.getName());
4.编写自定义过滤器
import org.apache.shiro.SecurityU
import org.apache.shiro.subject.S
import org.apache.shiro.web.filter.PathMatchingF
public class SysUserFilter extends PathMatchingFilter {
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
HttpServletRequest req = (HttpServletRequest)
HttpServletResponse res = (HttpServletResponse)
String url = req.getRequestURI();
Subject subject = SecurityUtils.getSubject();
String username = (String)subject.getPrincipal();
if(&superadmin&.equals(username)) {
return true;
Integer rulKey = this.matchingURL(url);
if(subject.isPermitted(rulKey+&&)) {
return true;
String method = req.getMethod();
String header = req.getHeader(&Accept&);
if(header.startsWith(&application/json&)) {
JSONObject responseJSONObject = new JSONObject();
responseJSONObject.put(&0&, &你没有该权限&);
res.setContentType(&application/ charset=utf-8&);
res.setCharacterEncoding(&UTF-8&);
PrintWriter out = null;
out = res.getWriter();
out.append(responseJSONObject.toString());
res.sendRedirect(&/unAuthc.html&);
return false;
*: matchingURL
*:根据当前请求地址获取标准的公共权限地址,只要是正常的访问。就应该能和公共权限中 一一对应查找到
* currentUrl
* Integer 获取到后,返回该公共地址的权限id,返回null,则表示请求的资源在公共权限库中没有找到(待定义处理)
* 日 下午4:00:40
* 日 下午4:00:40
private Integer matchingURL(String currentUrl) {
Map&Integer, String& authUrls = StaticCache.authU
for (Map.Entry&Integer, String& url : authUrls.entrySet()) {
if(currentUrl.contains(url.getValue())) {
return url.getKey();
return null;
用一张图来表示,shiro大概的入门调用流程,这个是自己花了一天时间理解的。也不知道对不对。反正就先这样用着先。
总结步骤:
1.添加shiro过滤器入口(一定要保证白过滤器在其他过滤器之前,至少在配置清单中在最前面)
2:配置安全管理器,设置自定义realm
3:配置web过滤器(也就是定义shiroFilter,定义的入口会搜寻该对象),设置权限,设置自定义过滤器拦截权限处理
本分类共有文章1篇,更多信息详见
& 2012 - 2016 &
&All Rights Reserved. &
/*爱悠闲图+*/
var cpro_id = "u1888441";在SpringMVC中开启Shiro注解授权的正确方法
在SpringMVC中开启Shiro注解授权的正确方法
临近年关,不知道是不是大家都空下来了,有时间学习了。最近好几个好学的童鞋在问我为什么他们在Srping的配置中文件中配置好了Shiro的注解支持Bean。但是在Controller中通过注解授权的时候就是不能生效。配置如下:
&span style=&font-size:14&&&bean id=&lifecycleBeanPostProcessor& class=&org.apache.shiro.spring.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&&/span&&/span&
首先我说,上面的配置是正确的,可是为什么不生效呢,今天我就来说说这事儿。
我们知道Shiro的注解授权是利有Spring的AOP实现的。在程序启动时会自动扫描作了注解的Class,当发现注解时,就自动注入授权代码实现。也就是说,要注入授权控制代码,第一处必须要让框架要可以扫描找被注解的Class 。而我们的Srping项目在ApplicationContext.xml中一般是不扫描Controller的,所以也就无法让写在Controller中的注解授权生效了。因此正确的作法是将这配置放到springmvc的配置文件中.这样Controller就可以通过注解授权了。
不过问题来了,通过上面的配置Controller是可以通过注解授权了,但是Services中依然不能通过注解授权。虽然说,如果我们在Controller控制了授权,那么对于内部调用的Service层就可以不再作授权,但也有例外的情况,比如Service除了给内部Controller层调用,还要供远程SOAP调用,那么就需要对Service进行授权控制了。同时要控制Controller和Service,那么采用相同的方式,我们可以在ApplicationContext.xml中配置类同的配置,以达到相同的效果。
&bean id=&serviceAdvisorAutoProxyCreator& class=&org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator&/&
&bean id=&serviceAuthorizationAttributeSourceAdvisor& class=&org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor&&
&property name=&securityManager& ref=&securityManager&/&
在springmvc.xml中的配置改为
&bean id=&controllerAdvisorAutoProxyCreator& class=&org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator&
depends-on=&lifecycleBeanPostProcessor&/&
&bean id=&controllerAuthorizationAttributeSourceAdvisor&
class=&org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor&&
&property name=&securityManager& ref=&securityManager&/&
此时,我们在同一个项目中配置了两个,DefaultAdvisorAutoProxyCreator 和AuthorizationAttributeSourceAdvisor.需要给它们指定不同的ID。
我的热门文章
即使是一小步也想与你分享springMvc和shiro整合,shiro的realm不能自动注入的问题_Java教程_动态网站制作指南
springMvc和shiro整合,shiro的realm不能自动注入的问题
来源:人气:1129
最近研究shiro,一开头就遇到了大困难,调试了3小时。问题描述如下:shiro和sing mvc整合,shiro自定义了realm。其中自定义的realm里面居然不能使用@Autowired注解标签相关的用户service。百思不得其解,一项项跟踪,发现原来shiro 自定义realm的认证阶段属于filter,当时的spring bean还没有读取进来。最后通过配置web.文件,把spring mvc的xml提高一点优先级,才最终解决了这个问题。
1 &!-- 配置spring容器监听器 --&
2 &context-param&
&param-name&contextConfigLocation&/param-name&
&param-value&
/WEB-INF/classes/Context-shiro.xml,
/WEB-INF/classes/spring-mvc.xml
&/param-value&
8 &/context-param&
9 &listener&
&listener-class&org.springframework.web.context.ContextLoaderListener&/listener-class&
11 &/listener&
13 !-- spring web程序的第一层控制器, 负责处理程序请求 --&
14 &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:spring-mvc.xml&/param-value&
&/init-param&
&load-on-startup&1&/load-on-startup&
22 &/servlet&
&servlet-mapping&
&servlet-name&springDispatcherServlet&/servlet-name&
&url-pattern&/&/url-pattern&
27 &/servlet-mapping&
注意红色这一项,我把springmvc的配置文件提上去,放到contextConfigLocation中去加载。
这样,就能在filter阶段注入其它已经注册了的bean。
具体参考了这篇文章:
http://blog.csdn.net/godha/article/details/
优质网站模板[摘要:本创做品,转载请标明:http://blog.csdn.net/xiejingfa/article/details/
比来有个小须要用到那几个框架,合腾了几天终究设置装备摆设出去,因而写下那篇。
原创作品,转载请标明:http://blog.csdn.net/xiejingfa/article/details/
最近有个小项目需要用到这几个框架,折腾了几天终于配置出来,于是写下这篇文章。
后端主要使用了Spring + SpringMVC + MyBatis + Shiro框架
前端是我在网上找的一个模板,主要是Bootstrap。
先来看看项目结构
配置完成后的
主要步骤:
1、Maven安装配置
(1)、下载Apache-maven-3.3.3,把它解压到某个路径,然后配置环境变量。完成之后可以在命令行中输入:mvn -来检查maven是否配置成功。
(2)、配置maven本地仓库。找到maven的安装路径,打开conf下的setting.xml文件。里面的localRepository标签即是配置本地仓库用得。先解除注释,然后配置一个本地目录,这样maven管理下得jar包就回下载到相应路径下。最后别忘了把该setting.xml文件复制一份到配置的目标目录下,方便与Eclipse集成。
(3)、再Eclipse中集成maven,在preferencs中配置以下内容:
2、创建一个名为Corwdsourcing的maven项目。注意,要把项目编码设置为utf-8。
3、配置pom.xml,引入相关jar包
&project xmlns=&http://maven.apache.org/POM/4.0.0& xmlns:xsi=&http://www.w3.org/2001/XMLSchema-instance&
xsi:schemaLocation=&http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&&
&modelVersion&4.0.0&/modelVersion&
&groupId&cn.edu.zju.eagle&/groupId&
&artifactId&Crowdsourcing&/artifactId&
&packaging&war&/packaging&
&version&0.0.1-SNAPSHOT&/version&
&name&Crowdsourcing Maven Webapp&/name&
&url&http://maven.apache.org&/url&
&properties&
&!-- spring --&
&spring.version&4.0.2.RELEASE&/spring.version&
&!-- mybatis版本号 --&
&mybatis.version&3.2.6&/mybatis.version&
&!-- log4j日志文件管理包版本 --&
&slf4j.version&1.7.7&/slf4j.version&
&log4j.version&1.2.17&/log4j.version&
&shiro.version&1.2.3&/shiro.version&
&/properties&
&dependencies&
&dependency&
&groupId&junit&/groupId&
&artifactId&junit&/artifactId&
&version&4.11&/version&
&!-- 表示开发的时候引入,发布的时候不会加载此包 --&
&scope&test&/scope&
&/dependency&
&!-- shiro --&
&dependency&
&groupId&org.apache.shiro&/groupId&
&artifactId&shiro-spring&/artifactId&
&version&${shiro.version}&/version&
&/dependency&
&dependency&
&groupId&org.apache.shiro&/groupId&
&artifactId&shiro-ehcache&/artifactId&
&version&${shiro.version}&/version&
&/dependency&
&dependency&
&groupId&org.apache.shiro&/groupId&
&artifactId&shiro-core&/artifactId&
&version&${shiro.version}&/version&
&/dependency&
&dependency&
&groupId&org.apache.shiro&/groupId&
&artifactId&shiro-web&/artifactId&
&version&${shiro.version}&/version&
&/dependency&
&dependency&
&groupId&org.apache.shiro&/groupId&
&artifactId&shiro-quartz&/artifactId&
&version&${shiro.version}&/version&
&/dependency&
&!-- spring核心包 --&
&dependency&
&groupId&org.springframework&/groupId&
&artifactId&spring-core&/artifactId&
&version&${spring.version}&/version&
&/dependency&
&dependency&
&groupId&org.springframework&/groupId&
&artifactId&spring-web&/artifactId&
&version&${spring.version}&/version&
&/dependency&
&dependency&
&groupId&org.springframework&/groupId&
&artifactId&spring-oxm&/artifactId&
&version&${spring.version}&/version&
&/dependency&
&dependency&
&groupId&org.springframework&/groupId&
&artifactId&spring-tx&/artifactId&
&version&${spring.version}&/version&
&/dependency&
&dependency&
&groupId&org.springframework&/groupId&
&artifactId&spring-jdbc&/artifactId&
&version&${spring.version}&/version&
&/dependency&
&dependency&
&groupId&org.springframework&/groupId&
&artifactId&spring-webmvc&/artifactId&
&version&${spring.version}&/version&
&/dependency&
&dependency&
&groupId&org.springframework&/groupId&
&artifactId&spring-aop&/artifactId&
&version&${spring.version}&/version&
&/dependency&
&dependency&
&groupId&org.springframework&/groupId&
&artifactId&spring-context-support&/artifactId&
&version&${spring.version}&/version&
&/dependency&
&dependency&
&groupId&org.springframework&/groupId&
&artifactId&spring-test&/artifactId&
&version&${spring.version}&/version&
&/dependency&
&!-- mybatis核心包 --&
&dependency&
&groupId&org.mybatis&/groupId&
&artifactId&mybatis&/artifactId&
&version&${mybatis.version}&/version&
&/dependency&
&!-- mybatis/spring包 --&
&dependency&
&groupId&org.mybatis&/groupId&
&artifactId&mybatis-spring&/artifactId&
&version&1.2.2&/version&
&/dependency&
&!-- 导入 ee jar 包 --&
&dependency&
&groupId&javax&/groupId&
&artifactId&javaee-api&/artifactId&
&version&7.0&/version&
&/dependency&
&!-- 导入链接jar包 --&
&dependency&
&groupId&mysql&/groupId&
&artifactId&mysql-connector-java&/artifactId&
&version&5.1.30&/version&
&/dependency&
&!-- 导入dbcp的jar包,用来在applicationContext.xml中配置数据库 --&
&dependency&
&groupId&commons-dbcp&/groupId&
&artifactId&commons-dbcp&/artifactId&
&version&1.2.2&/version&
&/dependency&
&!-- JSTL标签类 --&
&dependency&
&groupId&jstl&/groupId&
&artifactId&jstl&/artifactId&
&version&1.2&/version&
&/dependency&
&!-- 日志文件管理包 --&
&dependency&
&groupId&log4j&/groupId&
&artifactId&log4j&/artifactId&
&version&${log4j.version}&/version&
&/dependency&
&!-- JSON工具类 --&
&dependency&
&groupId&com.alibaba&/groupId&
&artifactId&fastjson&/artifactId&
&version&1.1.41&/version&
&/dependency&
&dependency&
&groupId&org.slf4j&/groupId&
&artifactId&slf4j-api&/artifactId&
&version&${slf4j.version}&/version&
&/dependency&
&dependency&
&groupId&org.slf4j&/groupId&
&artifactId&slf4j-log4j12&/artifactId&
&version&${slf4j.version}&/version&
&/dependency&
&!-- jackson --&
&dependency&
&groupId&org.codehaus.jackson&/groupId&
&artifactId&jackson-mapper-asl&/artifactId&
&version&1.9.13&/version&
&/dependency&
&!-- 上传组件包 --&
&dependency&
&groupId&commons-fileupload&/groupId&
&artifactId&commons-fileupload&/artifactId&
&version&1.3.1&/version&
&/dependency&
&dependency&
&groupId&commons-io&/groupId&
&artifactId&commons-io&/artifactId&
&version&2.4&/version&
&/dependency&
&dependency&
&groupId&commons-codec&/groupId&
&artifactId&commons-codec&/artifactId&
&version&1.9&/version&
&/dependency&
&/dependencies&
&finalName&Crowdsourcing&/finalName&
&/project&
4、整合Spring和MyBatis
(1)、jdbc.properties文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://10.214.52.238:3306/crowdsourcing?useUnicode=true&characterEncoding=utf-8
username=zhouyu
password=zhouyu
#定义初始连接数
initialSize=0
#定义最大连接数
maxActive=20
#定义最大空闲
maxIdle=20
#定义最小空闲
#定义最长等待时间
maxWait=60000
(2)、日志文件
#定义LOG输出级别
log4j.rootLogger=INFO,Console,File
#定义日志输出目的地为控制台
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.Target=.out
#可以灵活地指定日志输出格式,下面一行是指定具体的格式
log4j.appender.Console.layout = org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=[%c] - %m%n
#文件大小到达指定尺寸的时候产生一个新的文件
log4j.appender.File = org.apache.log4j.RollingFileAppender
#指定输出目录
log4j.appender.File.File = logs/ssm.log
#定义文件最大大小
log4j.appender.File.MaxFileSize = 10MB
# 输出所以日志,如果换成DEBUG表示输出DEBUG以上级别日志
log4j.appender.File.Threshold = ALL
log4j.appender.File.layout = org.apache.log4j.PatternLayout
log4j.appender.File.layout.ConversionPattern =[%p] [%d{yyyy-MM-dd HH\:mm\:ss}][%c]%m%n
(3)、applicationContex.xml文件。该文件主要用来整合Spring和MyBatis
&?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:p=&http://www.springframework.org/schema/p&
xmlns:context=&http://www.springframework.org/schema/context&
xmlns:mvc=&http://www.springframework.org/schema/mvc&
xsi:schemaLocation=&http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd&&
&!-- 自动扫描 --&
&context:component-scan base-package=&cn.edu.zju.eagle.crowdsourcing& /&
&!-- 引入配置文件 --&
&bean id=&propertyConfigurer&
class=&org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&&
&property name=&location& value=/"classpath:jdbc.properties" />
(4)、创建实体类、MyBatis映射文件、DAO层和Service层接口。前三者既可以手写,也可以利用MyBatis Generator自动创建。各文件如下:
cn.edu.zju.eagle.crowdsourcing.web.
import java.util.D
public class User {
public Date createT
/** 若该属性值等于0,表示该实体未被删除,若该属性值等于1,表示该实体类已被删除。 */
public Integer isD
public User() {
public User(String username, String password) {
this.username =
this.password =
public Integer getId() {
public void setId(Integer id) {
public String getUsername() {
public void setUsername(String username) {
this.username =
public String getPassword() {
public void setPassword(String password) {
this.password =
public Date getCreateTime() {
return createT
public void setCreateTime(Date createTime) {
this.createTime = createT
public Integer getIsDelete() {
return isD
public void setIsDelete(Integer isDelete) {
this.isDelete = isD
public String toString() {
return &User [id=& + id + &, username=& + username + &, password=& + password + &, createTime=& + createTime
+ &, isDelete=& + isDelete + &]&;
UserMapper映射文件
&?xml version=&1.0& encoding=&UTF-8&?&
&!DOCTYPE mapper PUBLIC &-//mybatis.org//DTD Mapper 3.0//EN& &http://mybatis.org/dtd/mybatis-3-mapper.dtd&&
&mapper namespace=&cn.edu.zju.eagle.crowdsourcing.web.dao.UserDao&&
&resultMap id=&BaseResultMap& type=&cn.edu.zju.eagle.crowdsourcing.web.model.User&&
&id column=&id& jdbcType=&INTEGER& property=&id& /&
&result column=&username& jdbcType=&VARCHAR& property=&username& /&
&result column=&password& jdbcType=&VARCHAR& property=&password& /&
&result column=&create_time& jdbcType=&TIMESTAMP& property=&createTime& /&
&result column=&is_delete& jdbcType=&INTEGER& property=&isDelete& /&
&/resultMap&
&sql id=&Base_Column_List&&
id, username, password, create_time, is_delete
&!-- 用户登录验证查询 --&
&select id=&authenticate& resultMap=&BaseResultMap&
parameterType=&map&&
&include refid=&Base_Column_List& /&
where username = #{record.username,jdbcType=VARCHAR} and
password =
#{record.password,jdbcType=VARCHAR} and is_delete = 0
&!-- 更新用户信息 --&
& id=&updateUser& parameterType=&cn.edu.zju.eagle.crowdsourcing.web.model.User&&
update user
&if test=&record.username != null&&
username = #{record.username,jdbcType=VARCHAR},
&if test=&record.password != null&&
password = #{record.password,jdbcType=VARCHAR},
where id = #{record.id,jdbcType=INTEGER} and is_delete = 0
UserDao.java文件
package cn.edu.zju.eagle.crowdsourcing.web.
import org.apache.ibatis.annotations.P
import cn.edu.zju.eagle.crowdsourcing.web.model.U
* 用户认证
* @param user 待认证用户
* @return 若认证失败,则返回User实例,否则返回null
public User authenticate(@Param(&record&) User record);
* 更新user信息
* @param record
* @return 受影响的行数
public int updateUser(@Param(&record&) User record);
UserServiceImpl.java
package cn.edu.zju.eagle.crowdsourcing.web.service.
import javax.annotation.R
import org.springframework.stereotype.S
import cn.edu.zju.eagle.crowdsourcing.web.dao.UserD
import cn.edu.zju.eagle.crowdsourcing.web.model.U
import cn.edu.zju.eagle.crowdsourcing.web.service.UserS
@Service(&userService&)
public class UserServiceImpl implements UserService {
private UserDao userD
public User authenticate(User user) {
return userDao.authenticate(user);
public int updateUser(User user) {
return userDao.updateUser(user);
5、整合SpringMVC
(1)、配置web.xml文件
&?xml version=&1.0& encoding=&UTF-8&?&
&web-app xmlns:xsi=&http://www.w3.org/2001/XMLSchema-instance&
xmlns=&/xml/ns/javaee&
xsi:schemaLocation=&/xml/ns/javaee /xml/ns/javaee/web-app_3_0.xsd&
version=&3.0&&
&display-name&Archetype Created Web Application&/display-name&
&!-- Spring和mybatis的 --&
&context-param&
&param-name&contextConfigLocation&/param-name&
&param-value&
classpath:applicationContext.xml
&/param-value&
&/context-param&
&!-- 编码过滤器 --&
&filter-name&encodingFilter&/filter-name&
&filter-class&org.springframework.web.filter.CharacterEncodingFilter&/filter-class&
&async-supported&true&/async-supported&
&init-param&
&param-name&encoding&/param-name&
&param-value&UTF-8&/param-value&
&/init-param&
&filter-mapping&
&filter-name&encodingFilter&/filter-name&
&url-pattern&/*&/url-pattern&
&/filter-mapping&
&!-- Spring监听器 --&
&listener&
&listener-class&org.springframework.web.context.ContextLoaderListener&/listener-class&
&/listener&
&!-- 防止Spring内存溢出监听器 --&
&listener&
&listener-class&org.springframework.web.util.IntrospectorCleanupListener&/listener-class&
&/listener&
&!-- Spring MVC servlet --&
&servlet-name&SpringMVC&/servlet-name&
&servlet-class&org.springframework.web.servlet.DispatcherServlet&/servlet-class&
&init-param&
&param-name&contextConfigLocation&/param-name&
&param-value&classpath:spring-mvc.xml&/param-value&
&/init-param&
&load-on-startup&1&/load-on-startup&
&async-supported&true&/async-supported&
&/servlet&
&servlet-mapping&
&servlet-name&SpringMVC&/servlet-name&
&!-- 此处可以可以配置成*.do,对应struts的后缀习惯 --&
&url-pattern&/&/url-pattern&
&/servlet-mapping&
&welcome-file-list&
&welcome-file&/index&/welcome-file&
&/welcome-file-list&
&/web-app&
(2)、配置spring-mvc.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:p=&http://www.springframework.org/schema/p&
xmlns:context=&http://www.springframework.org/schema/context&
xmlns:mvc=&http://www.springframework.org/schema/mvc&
xsi:schemaLocation=&http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd&&
&!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 --&
&context:component-scan base-package=&cn.edu.zju.eagle.crowdsourcing& /&
&!-- 访问静态文件 --&
&mvc:annotation-driven /&
&mvc:resources location=&/resources/& mapping=&/resources/**& /&
&!--避免IE执行AJAX时,返回JSON出现下载文件 --&
&bean id=&mappingJacksonHttpMessageConverter&
class=&org.springframework.http.converter.json.MappingJacksonHttpMessageConverter&&
&property name=&supportedMediaTypes&&
&value&text/charset=UTF-8&/value&
&/property&
&!-- 启动SpringMVC的注解功能,完成请求和注解POJO的映射 --&
class=&org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter&&
&property name=&messageConverters&&
&ref bean=&mappingJacksonHttpMessageConverter& /& &!-- JSON转换器 --&
&/property&
&!-- 定义跳转的文件的前后缀 ,视图模式配置--&
&bean class=&org.springframework.web.servlet.view.InternalResourceViewResolver&&
&!-- 这里的配置我的理解是自动给后面action的方法return的字符串加上前缀和后缀,变成一个 可用的url地址 --&
&property name=&prefix& value=/"/WEB-INF/views/" />
6、配置Shiro
(1)、applicationContex-shiro.xml
&?xml version=&1.0& encoding=&UTF-8&?&
&beans xmlns=&http://www.springframework.org/schema/beans& xmlns:util=&http://www.springframework.org/schema/util&
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
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd&&
&description&apache shiro配置&/description&
&bean id=&shiroFilter& class=&org.apache.shiro.spring.web.ShiroFilterFactoryBean&&
&property name=&securityManager& ref=&securityManager&/&
&property name=&loginUrl& value=/"/page/login"/>
/resources/** = anon
/user/login = anon
/page/login = anon
/** = authc
该文件需要用到自定义的Realm Bean完成权限检查和身份验证,这里定义为SecurityRealm.java
package cn.edu.zju.eagle.crowdsourcing.web.
import org.apache.log4j.L
import org.apache.shiro.authc.AuthenticationE
import org.apache.shiro.authc.AuthenticationI
import org.apache.shiro.authc.AuthenticationT
import org.apache.shiro.authc.SimpleAuthenticationI
import org.apache.shiro.authz.AuthorizationI
import org.apache.shiro.authz.SimpleAuthorizationI
import org.apache.shiro.realm.AuthorizingR
import org.apache.shiro.subject.PrincipalC
import org.
import cn.edu.zju.eagle.crowdsourcing.web.model.U
import cn.edu.zju.eagle.crowdsourcing.web.service.UserS
* 用户身份验证,授权 Realm 组件
* @author xiejingfa
@Component(value = /"securityRealm")
public class SecurityRealm extends AuthorizingRealm {
private static Logger logger = Logger.getLogger(SecurityRealm.class);
private UserService userS
public void setUserService(UserService userService) {
this.userService = userS
* 权限检查
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
String username = String.valueOf(principals.getPrimaryPrincipal());
System.out.println("doGetAuthorizationInfo username : " + username);
// 添加角色...
// 添加权限...
return authorizationI
* 登录验证
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = String.valueOf(token.getPrincipal());
String password = new String((char[]) token.getCredentials());
// 通过数据库进行验证
User unauthUser = new User();
unauthUser.username =
unauthUser.password =
final User authUser = userService.authenticate(unauthUser);
("待验证用户:" + unauthUser);
("验证结果:" + authUser);
if (authUser == null) {
throw new AuthenticationException("用户名或密码错误.");
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, getName());
return authenticationI
(2)、再web.xml中配置shiro过滤器和applicationContex-shiro.xml文件
package cn.edu.zju.eagle.crowdsourcing.web.
import org.apache.log4j.L
import org.apache.shiro.authc.AuthenticationE
import org.apache.shiro.authc.AuthenticationI
import org.apache.shiro.authc.AuthenticationT
import org.apache.shiro.authc.SimpleAuthenticationI
import org.apache.shiro.authz.AuthorizationI
import org.apache.shiro.authz.SimpleAuthorizationI
import org.apache.shiro.realm.AuthorizingR
import org.apache.shiro.subject.PrincipalC
import org.
import cn.edu.zju.eagle.crowdsourcing.web.model.U
import cn.edu.zju.eagle.crowdsourcing.web.service.UserS
* 用户身份验证,授权 Realm 组件
* @author xiejingfa
@Component(value = /"securityRealm")
public class SecurityRealm extends AuthorizingRealm {
private static Logger logger = Logger.getLogger(SecurityRealm.class);
private UserService userS
public void setUserService(UserService userService) {
this.userService = userS
* 权限检查
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
String username = String.valueOf(principals.getPrimaryPrincipal());
System.out.println("doGetAuthorizationInfo username : " + username);
// 添加角色...
// 添加权限...
return authorizationI
* 登录验证
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = String.valueOf(token.getPrincipal());
String password = new String((char[]) token.getCredentials());
// 通过数据库进行验证
User unauthUser = new User();
unauthUser.username =
unauthUser.password =
final User authUser = userService.authenticate(unauthUser);
("待验证用户:" + unauthUser);
("验证结果:" + authUser);
if (authUser == null) {
throw new AuthenticationException("用户名或密码错误.");
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, getName());
return authenticationI
(1)、编写Controller控制器类
package cn.edu.zju.eagle.crowdsourcing.web.
import javax.annotation.R
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpS
import javax.validation.V
import org.apache.log4j.L
import org.apache.shiro.SecurityU
import org.apache.shiro.authc.AuthenticationE
import org.apache.shiro.authc.UsernamePasswordT
import org.apache.shiro.subject.S
import org.springframework.stereotype.C
import org.springframework.ui.M
import org.springframework.validation.BindingR
import org.springframework.web.bind.annotation.RequestM
import org.springframework.web.bind.annotation.RequestM
import cn.edu.zju.eagle.crowdsourcing.web.model.U
import cn.edu.zju.eagle.crowdsourcing.web.service.UserS
@Controller
@RequestMapping(&/user&)
public class UserController {
private static Logger logger = Logger.getLogger(UserController.class);
private UserService userS
* 用户登录
* @param user
* @param result
@RequestMapping(value = /"/login", method = RequestMethod.POST)
public String login(@Valid User user, BindingResult result, Model model, HttpServletRequest request) {
System.out.println("login: " + user.toString());
Subject subject = SecurityUtils.getSubject();
// 已登陆则 跳到首页
if (subject.isAuthenticated()) {
(user.getUsername() + "已经登录");
return "redirect:/comm/index";
// 参数错误
if (result.hasErrors()) {
model.addAttribute("error", "参数错误!");
("参数错误");
return "redirect:/page/login";
// 身份验证
subject.login(new UsernamePasswordToken(user.getUsername(), user.getPassword()));
// 验证成功在Session中保存用户信息
final User authUserInfo = userService.authenticate(user);
request.getSession().setAttribute("userInfo", authUserInfo);
("登录成功" + authUserInfo);
} catch (AuthenticationException e) {
// 身份验证失败
model.addAttribute("error", "用户名或密码错误!");
(user.getUsername() + "用户名或密码错误");
return "redirect:/page/login";
(user.getUsername() + "登录成功");
return "redirect:/comm/index";
* 用户登出
* @param session
@RequestMapping(value="/logout", method=RequestMethod.GET)
public String logout(HttpSession session) {
session.removeAttribute("userInfo");
// 登出操作
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "redirect:/page/login";
(2)、导入数据库
-- phpMyAdmin SQL Dump
-- version 4.5.0.2
-- http://www.phpmyadmin.net
-- Generation Time:
-- 版本: 10.0.17-MariaDB
-- PHP Version: 5.6.14
SET SQL_MODE = &NO_AUTO_VALUE_ON_ZERO&;
SET time_zone = &+00:00&;
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
-- : `crowdsourcing`
-- --------------------------------------------------------
-- 表的结构 `user`
CREATE TABLE `user` (
`id` int(11) NOT NULL COMMENT '主键',
`username` varchar(128) NOT NULL COMMENT '用户名',
`password` varchar(256) NOT NULL COMMENT '密码',
`create_time` datetime NOT NULL COMMENT '注册时间',
`is_delete` int(11) NOT NULL DEFAULT '0' COMMENT '是否删除'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表';
-- 转存表中的数据 `user`
INSERT INTO `user` (`id`, `username`, `password`, `create_time`, `is_delete`) VALUES
(1, 'fred', '8d969eef6ecad3c29a3acf0c3f5d5a86aff3caadc6c92', ' 13:00:00', 0);
-- Indexes for dumped tables
-- Indexes for table `user`
ALTER TABLE `user`
ADD PRIMARY KEY (`id`);
-- AUTO_INCREMENT for dumped tables
-- AUTO_INCREMENT for table `user`
ALTER TABLE `user`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', AUTO_INCREMENT=2;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
到这里,完成了Spring + SpringMVC + MyBatis + Shiro的整合。}

我要回帖

更多关于 spring注解配置shiro 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信