shiro环境搭建及基本操作
分类:
IT文章
•
2024-04-04 22:50:33
一、pom.xml
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3 <modelVersion>4.0.0</modelVersion>
4 <groupId>com.sh</groupId>
5 <artifactId>shirotest</artifactId>
6 <packaging>war</packaging>
7 <version>0.0.1-SNAPSHOT</version>
8 <name>shirotest Maven Webapp</name>
9 <url>http://maven.apache.org</url>
10
11 <dependencies>
12
13
14 <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-all -->
15 <dependency>
16 <groupId>org.apache.shiro</groupId>
17 <artifactId>shiro-all</artifactId>
18 <version>1.2.2</version>
19 </dependency>
20 <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
21 <dependency>
22 <groupId>org.apache.commons</groupId>
23 <artifactId>commons-lang3</artifactId>
24 <version>3.4</version>
25 </dependency>
26
27
28 <dependency>
29 <groupId>javax.servlet</groupId>
30 <artifactId>servlet-api</artifactId>
31 <version>2.5</version>
32 <scope>provided</scope>
33 </dependency>
34 <dependency>
35 <groupId>junit</groupId>
36 <artifactId>junit</artifactId>
37 <version>3.8.1</version>
38 <scope>test</scope>
39 </dependency>
40 <!-- https://mvnrepository.com/artifact/jstl/jstl -->
41 <dependency>
42 <groupId>jstl</groupId>
43 <artifactId>jstl</artifactId>
44 <version>1.2</version>
45 </dependency>
46 <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
47 <dependency>
48 <groupId>org.springframework</groupId>
49 <artifactId>spring-aop</artifactId>
50 <version>3.2.0.RELEASE</version>
51 </dependency>
52 <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
53 <dependency>
54 <groupId>org.springframework</groupId>
55 <artifactId>spring-aspects</artifactId>
56 <version>3.2.0.RELEASE</version>
57 </dependency>
58 <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
59 <dependency>
60 <groupId>org.springframework</groupId>
61 <artifactId>spring-beans</artifactId>
62 <version>3.2.0.RELEASE</version>
63 </dependency>
64 <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
65 <dependency>
66 <groupId>org.springframework</groupId>
67 <artifactId>spring-context</artifactId>
68 <version>3.2.0.RELEASE</version>
69 </dependency>
70 <!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
71 <dependency>
72 <groupId>org.springframework</groupId>
73 <artifactId>spring-context-support</artifactId>
74 <version>3.2.0.RELEASE</version>
75 </dependency>
76 <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
77 <dependency>
78 <groupId>org.springframework</groupId>
79 <artifactId>spring-core</artifactId>
80 <version>3.2.0.RELEASE</version>
81 </dependency>
82 <!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
83 <dependency>
84 <groupId>org.springframework</groupId>
85 <artifactId>spring-expression</artifactId>
86 <version>3.2.0.RELEASE</version>
87 </dependency>
88 <!-- https://mvnrepository.com/artifact/org.springframework/spring-instrument -->
89 <dependency>
90 <groupId>org.springframework</groupId>
91 <artifactId>spring-instrument</artifactId>
92 <version>3.2.0.RELEASE</version>
93 </dependency>
94 <!-- https://mvnrepository.com/artifact/org.springframework/spring-instrument-tomcat -->
95 <dependency>
96 <groupId>org.springframework</groupId>
97 <artifactId>spring-instrument-tomcat</artifactId>
98 <version>3.2.0.RELEASE</version>
99 </dependency>
100 <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
101 <dependency>
102 <groupId>org.springframework</groupId>
103 <artifactId>spring-jdbc</artifactId>
104 <version>3.2.0.RELEASE</version>
105 </dependency>
106 <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
107 <dependency>
108 <groupId>org.springframework</groupId>
109 <artifactId>spring-orm</artifactId>
110 <version>3.2.0.RELEASE</version>
111 </dependency>
112 <!-- https://mvnrepository.com/artifact/org.springframework/spring-oxm -->
113 <dependency>
114 <groupId>org.springframework</groupId>
115 <artifactId>spring-oxm</artifactId>
116 <version>3.2.0.RELEASE</version>
117 </dependency>
118 <!-- https://mvnrepository.com/artifact/org.springframework/spring-struts -->
119 <dependency>
120 <groupId>org.springframework</groupId>
121 <artifactId>spring-struts</artifactId>
122 <version>3.2.0.RELEASE</version>
123 </dependency>
124 <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
125 <dependency>
126 <groupId>org.springframework</groupId>
127 <artifactId>spring-test</artifactId>
128 <version>3.2.0.RELEASE</version>
129 </dependency>
130 <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
131 <dependency>
132 <groupId>org.springframework</groupId>
133 <artifactId>spring-tx</artifactId>
134 <version>3.2.0.RELEASE</version>
135 </dependency>
136 <!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
137 <dependency>
138 <groupId>org.springframework</groupId>
139 <artifactId>spring-web</artifactId>
140 <version>3.2.0.RELEASE</version>
141 </dependency>
142 <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
143 <dependency>
144 <groupId>org.springframework</groupId>
145 <artifactId>spring-webmvc</artifactId>
146 <version>3.2.0.RELEASE</version>
147 </dependency>
148 <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc-portlet -->
149 <dependency>
150 <groupId>org.springframework</groupId>
151 <artifactId>spring-webmvc-portlet</artifactId>
152 <version>3.2.0.RELEASE</version>
153 </dependency>
154 </dependencies>
155 <build>
156 <finalName>shirotest</finalName>
157 </build>
158 </project>
View Code
二、SpringMvc.xml
1 <beans xmlns="http://www.springframework.org/schema/beans"
2 xmlns:context="http://www.springframework.org/schema/context"
3 xmlns:p="http://www.springframework.org/schema/p"
4 xmlns:mvc="http://www.springframework.org/schema/mvc"
5 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6 xsi:schemaLocation="http://www.springframework.org/schema/beans
7 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
8 http://www.springframework.org/schema/context
9 http://www.springframework.org/schema/context/spring-context.xsd
10 http://www.springframework.org/schema/mvc
11 http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
12 <!-- 启动注解驱动的Spring MVC功能,注册请求url和注解POJO类方法的映射-->
13 <mvc:annotation-driven />
14 <!-- 启动包扫描功能,以便注册带有@Controller、@Service、@repository、@Component等注解的类成为spring的bean -->
15 <context:component-scan base-package="com.**.controller" />
16 <mvc:default-servlet-handler/>
17 <!-- 对模型视图名称的解析,在请求时模型视图名称添加前后缀 -->
18 <!-- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/" p:suffix=".jsp" /> -->
19 <bean
20 class="org.springframework.web.servlet.view.InternalResourceViewResolver">
21 <property name="prefix">
22 <value>/</value>
23 </property>
24 <property name="suffix">
25 <value>.jsp</value>
26 </property>
27 </bean>
28
29 <!-- shiro注解启用,不可配置在shiro.xml中 -->
30 <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
31 <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
32 <property name="securityManager" ref="securityManager"/>
33 </bean>
34
35 <!-- shiro注解拦截未授权时跳转页面 -->
36 <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
37 <property name="exceptionMappings">
38 <props>
39 <prop key="org.apache.shiro.authz.AuthorizationException">
40 /meishouquan <!-- //捕获该异常时跳转的路径 -->
41 </prop>
42
43 </props>
44 </property>
45 </bean>
46 </beans>
View Code
三、web.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 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">
3 <session-config>
4 <session-timeout>120</session-timeout>
5 </session-config>
6 <context-param>
7 <param-name>contextConfigLocation</param-name>
8 <param-value>/WEB-INF/spring-*.xml</param-value>
9 </context-param>
10 <listener>
11 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
12 </listener>
13 <servlet-mapping>
14 <servlet-name>default</servlet-name>
15 <url-pattern>*.jpg</url-pattern>
16 </servlet-mapping>
17 <servlet-mapping>
18 <servlet-name>default</servlet-name>
19 <url-pattern>*.js</url-pattern>
20 </servlet-mapping>
21 <servlet-mapping>
22 <servlet-name>default</servlet-name>
23 <url-pattern>*.css</url-pattern>
24 </servlet-mapping>
25 <servlet-mapping>
26 <servlet-name>default</servlet-name>
27 <url-pattern>*.docx</url-pattern>
28 </servlet-mapping>
29 <servlet>
30 <servlet-name>spring</servlet-name>
31 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
32 <load-on-startup>1</load-on-startup>
33 </servlet>
34 <servlet-mapping>
35 <servlet-name>spring</servlet-name>
36 <url-pattern>/</url-pattern>
37 </servlet-mapping>
38
39 <!--
40 配置Shiro过滤器
41 这里filter-name必须对应spring-shiro.xml中定义的<bean />
42 使用[/*]匹配所有请求,保证所有的可控请求都经过Shiro的过滤
43 通常会将此filter-mapping放置到最前面(即其他filter-mapping前面),以保证它是过滤器链中第一个起作用的
44 -->
45 <filter>
46 <filter-name>shiroFilter</filter-name>
47 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
48 <init-param>
49 <!-- 缺省为false,表示由SpringApplicationContext管理生命周期,置为true则表示由ServletContainer管理 -->
50 <param-name>targetFilterLifecycle</param-name>
51 <param-value>true</param-value>
52 </init-param>
53 </filter>
54 <filter-mapping>
55 <filter-name>shiroFilter</filter-name>
56 <url-pattern>/*</url-pattern>
57 </filter-mapping>
58 </web-app>
View Code
四、spring-shiro.xml
1 <beans xmlns="http://www.springframework.org/schema/beans"
2 xmlns:context="http://www.springframework.org/schema/context"
3 xmlns:p="http://www.springframework.org/schema/p"
4 xmlns:mvc="http://www.springframework.org/schema/mvc"
5 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6 xsi:schemaLocation="http://www.springframework.org/schema/beans
7 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
8 http://www.springframework.org/schema/context
9 http://www.springframework.org/schema/context/spring-context.xsd
10 http://www.springframework.org/schema/mvc
11 http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
12
13
14 <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
15 <!-- 指定Shiro验证用户登录的类为自定义的Realm(若有多个Realm,可使用[realms]属性代替) -->
16 <property name="realm">
17 <bean class="com.sh.realm.MyRealm"/>
18 </property>
19 <!--
20 Shiro默认会使用Servlet容器的Session,此时修改超时时间的话,可以修改web.xml或者这里自定义的MyRealm
21 而若想使用Shiro原生Session则可以设置sessionMode属性为native,此时修改超时时间则只能修改MyRealm
22 -->
23 <!-- <property name="sessionMode" value="native"/> -->
24 </bean>
25
26 <!-- Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的、自定义的过滤器的执行 -->
27 <!-- Web应用中,Shiro可控制的Web请求必须经过Shiro主过滤器的拦截,并且Shiro对基于Spring的Web应用提供了完美的支持 -->
28 <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
29 <!-- Shiro的核心安全接口,这个属性是必须的 -->
30 <property name="securityManager" ref="securityManager"/>
31 <!-- 要求登录时的链接(可根据项目的URL进行替换),非必须的属性,默认会找Web工程根目录下的[/login.jsp] -->
32 <property name="loginUrl" value="/login.jsp"/>
33 <!-- 登录成功后要跳转的连接(本例中此属性用不到,因为登录成功后的处理逻辑已在LoginController中硬编码为main.jsp) -->
34 <!-- <property name="successUrl" value="/system/main"/> -->
35 <!-- 用户访问未授权的资源时,跳转页面-->
36 <property name="unauthorizedUrl" value="/meishouquan.jsp"/>
37 <!--拦截配置-->
38 <property name="filterChainDefinitions">
39 <value>
40 /admin/list** = authc,perms[admin:manage,admin:add] <!-- 必须登陆,并且具有[]里的权限才可访问 -->
41 <!-- /admin/list** = authc,roles[admin] --> <!-- 必须登陆,并且具有[]里的角色才可访问 -->
42 /user/info-anon** = anon<!-- 无需登录 -->
43 /user/info** = authc<!-- 需要登陆 -->
44 </value>
45 </property>
46 </bean>
47
48 <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
49 <!-- http://shiro.apache.org/static/1.2.1/apidocs/org/apache/shiro/spring/LifecycleBeanPostProcessor.html -->
50 <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
51
52
53 <!--开启Shiro的注解(比如@RequiresRoles、@RequiresPermissions) 配置以下两个bean即可实现此功能-->
54
55 <!-- 注意:**下面配置只能在spring.xml中配置生效,必须保证在加载第一个xml时加载此配置 -->
56
57 <!-- <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
58 <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
59 <property name="securityManager" ref="securityManager"/>
60 </bean> -->
61
62
63 </beans>
View Code
1 package com.sh.controller;
2
3 import java.io.IOException;
4
5 import javax.servlet.http.HttpServletRequest;
6 import javax.servlet.http.HttpServletResponse;
7 import javax.servlet.http.HttpSession;
8
9 import org.apache.commons.lang3.StringUtils;
10 import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
11 import org.apache.commons.lang3.builder.ToStringStyle;
12 import org.apache.shiro.SecurityUtils;
13 import org.apache.shiro.authc.AuthenticationException;
14 import org.apache.shiro.authc.ExcessiveAttemptsException;
15 import org.apache.shiro.authc.IncorrectCredentialsException;
16 import org.apache.shiro.authc.LockedAccountException;
17 import org.apache.shiro.authc.UnknownAccountException;
18 import org.apache.shiro.authc.UsernamePasswordToken;
19 import org.apache.shiro.authz.annotation.RequiresGuest;
20 import org.apache.shiro.authz.annotation.RequiresPermissions;
21 import org.apache.shiro.authz.annotation.RequiresRoles;
22 import org.apache.shiro.authz.annotation.RequiresUser;
23 import org.apache.shiro.subject.Subject;
24 import org.apache.shiro.web.util.WebUtils;
25 import org.springframework.stereotype.Controller;
26 import org.springframework.web.bind.annotation.RequestMapping;
27 import org.springframework.web.bind.annotation.RequestMethod;
28 import org.springframework.web.servlet.view.InternalResourceViewResolver;
29
30 /**
31 * SpringMVC-3.2.4整合Shiro-1.2.2
32 */
33 @Controller
34 @RequestMapping("mydemo")
35 public class ShiroUserController {
36 @RequestMapping(value="/test", method=RequestMethod.GET)
37 public void test(String username, String password, HttpServletRequest request,HttpServletResponse response) throws IOException{
38 //Subject currentUser = SecurityUtils.getSubject();
39 // System.out.println(currentUser.);
40 /*System.out.println(currentUser.isPermitted("admin:manage1"));//判断是否有指定权限
41 System.out.println(currentUser.hasRole("admin1"));//判断是否有指定角色*/
42 Object principal = SecurityUtils.getSubject().getPrincipal();//获得当前登录用户名
43 response.getWriter().print(principal);
44 }
45 @RequestMapping("/logout")
46 public String logout(HttpSession session){
47 String currentUser = (String)session.getAttribute("currentUser");
48 System.out.println("用户[" + currentUser + "]准备登出");
49 SecurityUtils.getSubject().logout();
50 System.out.println("用户[" + currentUser + "]已登出");
51 return InternalResourceViewResolver.REDIRECT_URL_PREFIX + "/login.jsp";
52 }
53
54 @RequestMapping(value="/login", method=RequestMethod.POST)
55 public String login(String username, String password, HttpServletRequest request){
56 System.out.println("-------------------------------------------------------");
57 String rand = (String)request.getSession().getAttribute("rand");
58 String captcha = WebUtils.getCleanParam(request, "captcha");
59 System.out.println("用户["+username+"]登录时输入的验证码为["+captcha+"],HttpSession中的验证码为["+rand+"]");
60 if(!StringUtils.equals(rand, captcha)){
61 request.setAttribute("message_login", "验证码不正确");
62 return InternalResourceViewResolver.FORWARD_URL_PREFIX + "/";
63 }
64 UsernamePasswordToken token = new UsernamePasswordToken(username, password);
65 // token.setRememberMe(true);
66 System.out.print("为验证登录用户而封装的Token:");
67 System.out.println(ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE));
68 //获取当前的Subject
69 Subject currentUser = SecurityUtils.getSubject();
70 try {
71 //在调用了login方法后,SecurityManager会收到AuthenticationToken,并将其发送给已配置的Realm执行必须的认证检查
72 //每个Realm都能在必要时对提交的AuthenticationTokens作出反应
73 //所以这一步在调用login(token)方法时,它会走到MyRealm.doGetAuthenticationInfo()方法中,具体验证方式详见此方法
74 System.out.println("对用户[" + username + "]进行登录验证...验证开始");
75 currentUser.login(token);
76 System.out.println("对用户[" + username + "]进行登录验证...验证通过");
77 }catch(UnknownAccountException uae){
78 System.out.println("对用户[" + username + "]进行登录验证...验证未通过,未知账户");
79 request.setAttribute("message_login", "未知账户");
80 }catch(IncorrectCredentialsException ice){
81 System.out.println("对用户[" + username + "]进行登录验证...验证未通过,错误的凭证");
82 request.setAttribute("message_login", "密码不正确");
83 }catch(LockedAccountException lae){
84 System.out.println("对用户[" + username + "]进行登录验证...验证未通过,账户已锁定");
85 request.setAttribute("message_login", "账户已锁定");
86 }catch(ExcessiveAttemptsException eae){
87 System.out.println("对用户[" + username + "]进行登录验证...验证未通过,错误次数过多");
88 request.setAttribute("message_login", "用户名或密码错误次数过多");
89 }catch(AuthenticationException ae){
90 //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
91 System.out.println("对用户[" + username + "]进行登录验证...验证未通过,堆栈轨迹如下");
92 ae.printStackTrace();
93 request.setAttribute("message_login", "用户名或密码不正确");
94 }
95 //验证是否登录成功
96 if(currentUser.isAuthenticated()){
97 System.out.println("用户[" + username + "]登录认证通过(这里可进行一些认证通过后的系统参数初始化操作)");
98 return "main";
99 }else{
100 token.clear();
101 return InternalResourceViewResolver.FORWARD_URL_PREFIX + "/";
102 }
103 }
104 //属于admin角色
105 //@RequiresRoles("admin")
106 //必须同时属于user和admin角色
107 @RequiresRoles({"user","admin"})
108 //属于user或者admin之一;修改logical为OR 即可
109 //@RequiresRoles(value={"user","admin"},logical=Logical.OR)
110 @RequestMapping(value="/useRoles")
111 public void requiresRoles(HttpServletRequest request, HttpServletResponse response){
112 System.out.println("必须拥有指定角色");
113 }
114 //符合index:hello权限要求
115 @RequiresPermissions("admin:manage")
116 //必须同时复核index:hello和index:world权限要求
117 //@RequiresPermissions({"index:hello","index:world"})
118 //符合index:hello或index:world权限要求即可
119 //@RequiresPermissions(value={"index:hello","index:world"},logical=Logical.OR)
120 @RequestMapping(value="/useper")
121 public void requiresPermissions(HttpServletRequest request, HttpServletResponse response){
122 System.out.println("必须拥有指定权限");
123 }
124 /* 验证用户是否被记忆,user有两种含义:
125 一种是成功登录的(subject.isAuthenticated() 结果为true);
126 另外一种是被记忆的(subject.isRemembered()结果为true)。*/
127 @RequiresUser
128 @RequestMapping(value="/islogin")
129 public void requiresUser(HttpServletRequest request, HttpServletResponse response){
130 System.out.println("必须登录或者记住登录的");
131 }
132 //必须游客访问
133 @RequiresGuest
134 @RequestMapping(value="/isguest")
135 public void requiresGuest(HttpServletRequest request, HttpServletResponse response){
136 System.out.println("必须游客");
137 }
138 }