-
-
-
-
-
-
抽象的类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
package
com.book.admin.interceptor;
import
java.util.ArrayList;
import
java.util.List;
import
java.util.regex.Pattern;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
org.slf4j.Logger;
import
org.slf4j.LoggerFactory;
import
org.springframework.web.servlet.HandlerInterceptor;
import
org.springframework.web.servlet.ModelAndView;
/**
*
* @author liweihan
*
*/
public
abstract
class
AbstractInterceptor
implements
HandlerInterceptor{
private
static
Logger logger = LoggerFactory.getLogger(AbstractInterceptor.
class
);
//不需要拦截的链接
protected
static
List<String> excludeActionList =
new
ArrayList<String>();
static
{
excludeActionList.add(
"^/(login|static)(/)?(.+)?$"
);
excludeActionList.add(
"^/(flush|test|site_map)(/)?(.+)?$"
);
//redis data flush
excludeActionList.add(
"^/app/(flush|info.json|apkinfo.json)(/)?(.+)?$"
);
//前端接口http://m.tv.sohu.com/app
excludeActionList.add(
"^/(hikeapp)(/)?(.+)?$"
);
//需要拉起客户端的专辑数据访问接口
excludeActionList.add(
"^/(cooperation|activity|api|open|mobile|mb)(/)?(.+)?$"
);
excludeActionList.add(
"^/(activity|api|open|mobile|mb)(/)?(.+)?$"
);
excludeActionList.add(
"^/(test)(/)?(.+)?$"
);
}
public
boolean
preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler)
throws
Exception {
// logger.debug(" ====== prehandle !");
// logger.info(" ======= URI:{}",request.getRequestURI());
request.setAttribute(
"uri"
, request.getRequestURI());
//为了突出显示选中的链接
for
(String excludeUrl : excludeActionList) {
if
(Pattern.matches(excludeUrl, request.getRequestURI())) {
return
true
;
}
}
return
innerPreHandle(request, response, handler);
}
protected
abstract
boolean
innerPreHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws
Exception;
public
void
postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView)
throws
Exception {
// logger.debug(" ====== postHandle !");
}
public
void
afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws
Exception {
// logger.debug(" ====== afterCompletion !");
}
}
|
2.权限过滤
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
package
com.book.admin.interceptor;
import
java.util.ArrayList;
import
java.util.List;
import
java.util.regex.Pattern;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
org.apache.commons.lang.StringUtils;
import
org.slf4j.Logger;
import
org.slf4j.LoggerFactory;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.web.util.WebUtils;
import
com.book.core.model.AdminFunctions;
import
com.book.core.model.AdminRight;
import
com.book.core.model.User;
import
com.book.core.service.AdminFunctionsService;
import
com.book.core.service.AdminRightService;
import
com.book.core.utils.Constants;
/**
* 用户权限过滤
* @author liweihan
*
*/
public
class
FunctionsInterceptor
extends
AbstractInterceptor{
private
static
Logger logger = LoggerFactory.getLogger(FunctionsInterceptor.
class
);
@Autowired
private
AdminRightService adminRightService;
@Autowired
private
AdminFunctionsService adminFunctionsService;
//登录后不需要拦截的链接
protected
static
List<String> excludeActionList =
new
ArrayList<String>();
static
{
excludeActionList.add(
"^/(index|admin/user|admin/myinfo)(/)?(.+)?$"
);
excludeActionList.add(
"^/(book/del|book/detail.json|book/addorupdate)(/)?(.+)?$"
);
}
@Override
protected
boolean
innerPreHandle(HttpServletRequest request,
HttpServletResponse response, Object handler)
throws
Exception {
try
{
User user = (User) WebUtils.getSessionAttribute(request, Constants.ADMIN_SESSION_USER_KEY);
if
(user ==
null
) {
response.sendRedirect(
"/login"
);
return
false
;
}
//查找该用户的权限
AdminRight adminRight = adminRightService.getObjByUserName(user.getName());
if
(adminRight ==
null
) {
return
true
;
}
List<AdminFunctions> menus =
null
;
if
(adminRight.getIsAdmin() ==
1
) {
menus = adminFunctionsService.getAll();
request.setAttribute(
"menus"
, menus);
request.setAttribute(
"isAdmin"
, adminRight.getIsAdmin());
return
true
;
}
else
{
String right = adminRight.getRights();
if
(StringUtils.isNotBlank(right)) {
String[] rs = right.split(
","
);
List<Integer> listId =
null
;
if
(rs !=
null
&& rs.length >
0
) {
listId =
new
ArrayList<Integer>();
for
(
int
i =
0
; i < rs.length; i++) {
if
(StringUtils.isNotBlank(rs[i])) {
listId.add(Integer.valueOf(rs[i]));
}
}
}
//查询
menus = adminFunctionsService.getObjByIds(listId);
}
for
(String excludeUrl : excludeActionList) {
if
(Pattern.matches(excludeUrl, request.getRequestURI())) {
request.setAttribute(
"menus"
, menus);
request.setAttribute(
"isAdmin"
, adminRight.getIsAdmin());
return
true
;
}
}
//对权限进行过滤,不能输入URL就可以访问
if
(menus !=
null
&& menus.size() >
0
) {
for
(AdminFunctions adminFunctions : menus) {
if
(request.getRequestURI().startsWith(adminFunctions.getUrl())) {
logger.info(
" ====== request.getRequestURI():{},table-url:{}"
,request.getRequestURI(),adminFunctions.getUrl());
request.setAttribute(
"menus"
, menus);
request.setAttribute(
"isAdmin"
, adminRight.getIsAdmin());
return
true
;
}
}
}
}
response.sendRedirect(
"/login"
);
return
false
;
}
catch
(Exception e) {
logger.error(
" ====== get AdminRight error!"
,e);
e.printStackTrace();
}
return
false
;
}
}
|
3.登录验证
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
package
com.book.admin.interceptor;
import
java.net.URLEncoder;
import
java.util.Calendar;
import
java.util.Date;
import
java.util.UUID;
import
javax.servlet.http.Cookie;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
org.slf4j.Logger;
import
org.slf4j.LoggerFactory;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.web.util.WebUtils;
import
com.book.core.model.PersistentLogins;
import
com.book.core.model.User;
import
com.book.core.service.PersistentLoginsService;
import
com.book.core.service.UserService;
import
com.book.core.utils.Constants;
import
com.book.core.utils.CookieUtil;
import
com.book.core.utils.EncryptionUtil;
/**
* 登录验证拦截器
* @author liweihan
*
*/
public
class
LoginInterceptor
extends
AbstractInterceptor{
private
static
Logger logger = LoggerFactory.getLogger(LoginInterceptor.
class
);
@Autowired
private
PersistentLoginsService persistentLoginsService;
@Autowired
private
UserService userService;
@Override
protected
boolean
innerPreHandle(HttpServletRequest request,
HttpServletResponse response, Object handler)
throws
Exception {
User user = (User) WebUtils.getSessionAttribute(request, Constants.ADMIN_SESSION_USER_KEY);
if
(user !=
null
) {
//已登录
return
true
;
}
else
{
//从cookie中取值
Cookie cookie = CookieUtil.getCookie(request, Constants.RememberMe_Admin);
if
(cookie !=
null
) {
String cookieValue = EncryptionUtil.base64Decode(cookie.getValue());
String[] cValues = cookieValue.split(
":"
);
if
(cValues.length ==
2
) {
String userNameByCookie = cValues[
0
];
//获取用户名
String uuidByCookie = cValues[
1
];
//获取UUID值
//到数据库中查询自动登录记录
PersistentLogins pLogins = persistentLoginsService.getObjByUUID(uuidByCookie);
if
(pLogins !=
null
) {
String savedToken = pLogins.getToken();
//获取有效时间
Date savedValidTime = pLogins.getValidTime();
Date currentTime =
new
Date();
//如果还在有效期内,记录判断是否可以自动登录
if
(currentTime.before(savedValidTime)) {
User u = userService.getUserByName(userNameByCookie);
if
(u !=
null
) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(savedValidTime);
// 精确到分的时间字符串
String timeString = calendar.get(Calendar.YEAR) +
"-"
+ calendar.get(Calendar.MONTH)
+
"-"
+ calendar.get(Calendar.DAY_OF_MONTH) +
"-"
+ calendar.get(Calendar.HOUR_OF_DAY) +
"-"
+ calendar.get(Calendar.MINUTE);
// 为了校验而生成的密文
String newToken = EncryptionUtil.sha256Hex(u.getName() +
"_"
+ u.getPassword() +
"_"
+ timeString +
"_"
+ Constants.salt);
// 校验sha256加密的值,如果不一样则表示用户部分信息已被修改,需要重新登录
if
(savedToken.equals(newToken)) {
//为了提高安全性,每次登录之后都更新自动登录的cookie值
String uuidNewString = UUID.randomUUID().toString();
String newCookieValue = EncryptionUtil.base64Encode(u.getName() +
":"
+ uuidNewString);
CookieUtil.editCookie(request, response, Constants.RememberMe_Admin, newCookieValue,
null
);
//同时更新数据
pLogins.setSeries(uuidNewString);
pLogins.setUpdateTime(
new
Date());
persistentLoginsService.updateByObj(pLogins);
//将用户加到session中,不退出浏览器时只需要判断session即可
WebUtils.setSessionAttribute(request, Constants.ADMIN_SESSION_USER_KEY, u);
//校验成功,此次拦截操作完成
return
true
;
}
else
{
//用户信息部分被修改,删除cookie并清空数据库中的记录
CookieUtil.delCookie(response, cookie);
persistentLoginsService.delObjById(pLogins.getId());
}
}
}
else
{
// 超过保存的有效期,删除cookie并清空数据库中的记录
CookieUtil.delCookie(response, cookie);
persistentLoginsService.delObjById(pLogins.getId());
}
}
}
}
try
{
response.sendRedirect(
"/login?src="
+ URLEncoder.encode(request.getRequestURI(),
"UTF-8"
));
}
catch
(Exception e) {
logger.error(
" ===== loginInterceptor error ,url:{}{}"
,request.getRequestURL(),request.getRequestURI(),e);
}
return
false
;
}
}
}
|
4.spring-mvc-servlet.xml的配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
<?
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/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- 指定一个包让其自动扫描 -->
<
context:component-scan
base-package
=
"com.book.admin.controller"
/>
<
mvc:annotation-driven
/>
<!-- 下面注释的部分表示:强调所有的请求都要经过springmvc框架 -->
<
mvc:default-servlet-handler
/>
<!-- 放行了以/static/开始的请求 -->
<
mvc:resources
location
=
"/static/"
mapping
=
"/static/**"
/>
<!-- 当一个方法完全是为了跳转时,我们可以省略该方法,而在此写一个配置就行了
<mvc:view-controller path="/index" view-name="index"/>
<mvc:view-controller path="/main" view-name="main"/>
<mvc:view-controller path="/success" view-name="success"/>
<mvc:view-controller path="/index" view-name="main"/>
<mvc:view-controller path="/" view-name="main"/>
<mvc:view-controller path="/admin/myinfo" view-name="myinfo"/>-->
<!--
<mvc:view-controller path="/book" view-name="book"/>
-->
<
mvc:interceptors
>
<
bean
class
=
"com.book.admin.interceptor.LoginInterceptor"
></
bean
>
<
bean
class
=
"com.book.admin.interceptor.FunctionsInterceptor"
></
bean
>
<!--
<mvc:interceptor>
<mvc:mapping path="/test/number.do"/>
<bean class="com.host.app.web.interceptor.LoginInterceptor"/>
</mvc:interceptor>
-->
</
mvc:interceptors
>
<!-- 配置springmvc的视图解析器 -->
<
bean
id
=
"viewResolver"
class
=
"org.springframework.web.servlet.view.InternalResourceViewResolver"
>
<
property
name
=
"suffix"
value
=
".jsp"
/>
<
property
name
=
"prefix"
value
=
"/WEB-INF/views/"
/>
</
bean
>
<!-- 文件上传解析器 -->
<
bean
id
=
"multipartResolver"
class
=
"org.springframework.web.multipart.commons.CommonsMultipartResolver"
>
<
property
name
=
"maxUploadSize"
value
=
"100000"
/>
</
bean
>
</
beans
>
|
参考:
拦截器的基础了解
http://blog.csdn.net/sunp823/article/details/51694662
拦截器的详细了解
http://jinnianshilongnian.iteye.com/blog/1670856
登录例子的思路了解
http://blog.51cto.com/983836259/1880284
正则表达式
http://www.cnblogs.com/sparkbj/articles/6207103.html
springmvc的拦截器和过滤器的区别
http://blog.csdn.net/xiaoyaotan_111/article/details/53817918
java Web中的过滤器Filter和interceptor的理解
http://www.jianshu.com/p/39c0cfe25997
本文转自韩立伟 51CTO博客,原文链接:http://blog.51cto.com/hanchaohan/2047966,如需转载请自行联系原作者