(四)、过滤器处理
在过滤器当中需要添加一些不需要进行token校验的请求路径,可以直接访问。 在这里没有角色权限的校验,有需要的可以自行设计。
Java code?
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
package
ichano.developer.sys.filter;
`/**`
import ichano.developer.biz.service.ZyLoginService;
import ichano.developer.dto.ZyUserDto;
import ichano.developer.util.KeyUtil;
import ichano.developer.util.TokenUtil;
import java.io.IOException;
import java.security.Key;
import javax.annotation.Priority;
import javax.inject.Inject;
import javax.servlet.ServletContext;
import javax.ws.rs.Priorities;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.Provider;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.glassfish.jersey.server.ContainerRequest;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @ClassName: JWTSecurityFilter
* @Description: TODO(权限验证过滤器)
* @author lizhijun
* @date 2016年8月11日 下午1:18:52
*
*/
@Provider
@Priority
`(Priorities.AUTHENTICATION)`//优先级最高
//实现该拦截器借口
//@Provider可以自动注册
@PreMatching
//这个必须添加,否则无法拦截请求
public
class
JWTSecurityFilter
`implements
ContainerRequestFilter{`
final
static
Logger logger = LogManager.getLogger(JWTSecurityFilter.
`class`.getName());
@Autowired
ZyLoginService zyLoginService;
@Context
ServletContext context;
@Inject
javax.inject.Provider<UriInfo> uriInfo;
public
static
String extractJwtTokenFromAuthorizationHeader(String auth) {
//Replacing "Bearer Token" to "Token" directly
return
auth.replaceFirst(
`"B|bA|aE|e ",
"").replace(
" ",
""`);
}
//重写验证过滤器
@Override
public
void
filter(ContainerRequestContext containerRequestContext)
`throws
IOException {`
//获取本地的私钥
Key key= KeyUtil.getKey(context);
//得到访问的方法 例如GET,POST
String method = containerRequestContext.getMethod().toLowerCase();
//预校验请求处理
if
`(method.equals("options"
)){`
containerRequestContext.setSecurityContext(
`new
SecurityContextAuthorizer(uriInfo,new` `AuthorPricinple(
"pass"),
new
String[]{"pass"
}));`
return
`;`
}
//得到访问路径
String path = ((ContainerRequest) containerRequestContext).getPath(
`true`).toLowerCase();
System.err.println(
`"authorizationHeader path is :"`+path);
//不需要验证,post验证过滤,注册过滤。
if
(
`"post".equals(method) &&
"developer/loginuser"`.equals(path)
||
`"developer/registeruser"`.equals(path)
||
`"developer/sendverifcode"`.equals(path)
||
`"developer/updatepwd"`.equals(path)
||
`"license/uploadfilecheck"`.equals(path)
||
`"product/uploadproductimg"`.equals(path)) {
containerRequestContext.setSecurityContext(
`new
SecurityContextAuthorizer(uriInfo,new` `AuthorPricinple(
"pass"),
new
String[]{"pass"
}));`
return
`;`
}
//获取头信息中的token
MultivaluedMap<String, String> testToken = ((ContainerRequest) containerRequestContext).getHeaders();
String authorizationHeader = ((ContainerRequest) containerRequestContext).getHeaderString(
`"auth_token"`);
//如果token为空抛出
if
(authorizationHeader ==
`null`) {
throw
new
WebApplicationException(Response.Status.UNAUTHORIZED);
`//抛出未认证的错误`
}
//把Bear Token换成Token
String strToken=extractJwtTokenFromAuthorizationHeader(authorizationHeader);
if
(TokenUtil.isValid(strToken,key)){
String name=TokenUtil.getName(strToken,key);
`//反解出Name`
// String[] roles=TokenUtil.getRoles(strToken,key);//反解出角色
if
`(name !=null
){`
ZyUserDto user=zyLoginService.findUserByName(name);
if
`(user!=null
){`
containerRequestContext.setSecurityContext(
`new
SecurityContextAuthorizer(uriInfo,new` `AuthorPricinple(name),
new
String[]{"user"
}));`
return
`;`
}
else
`{`
logger.info(
`"User not found "
+ name);`
}
}
else
{
logger.info(
`"name, roles or version missing from token"`);
}
}
else
{
logger.info(
`"token is invalid"`);
}
throw
new
WebApplicationException(Response.Status.UNAUTHORIZED);
}
}
(五)、前端请求代码:
采用ajax post请求方式。
// 发送登陆请求
JavaScript code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$.ajax({
url:
`"http://192.168.0.55:8080/developer/developer/loginUser"`,
type:
`"POST"`,
dataType:
`"json"`,
contentType:
`"application/json", <span style=
"color: #FF0000;">
//注意:如果有post data参数的时候,必须加这段,否则请求获取不到参数</span> `
data: {
user_name: userName,
password: userPwd,
type: type
},
success:
`function`(data) {
console.log(data);
if
(data.code == 1000) {
$.cookie(
`'token'`, data.data.token);
console.log(1);
parent.location.reload();
}
`else
if
(data.code == 2006) {`
layer.msg(
`"用户名密码错误"`);
}
`else
{`
layer.msg(
`"登陆异常"`);
}
}
});
//访问接口请求
JavaScript code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$.ajax({
url:
`"http://192.168.0.181:9102/developer/developer/checkLogin"`,
type:
`'POST'`,
dataType:
`'json'`,
beforeSend:
`function(request) {
//添加请求响应头中的自定义token`
request.setRequestHeader(
`"auth_token"`, token);
},
success:
`function`(data) {
if
(data.code == 1000) {
var
html = [];
html.push(Mustache.render(userNameTemp, data.data));
$userNameCon.html(html.join(
`''`));
}
`else
{`
window.location.href =
`"index.html"`
}
}
})
二、CORS跨域访问
使用cors进行跨域配置其实很简单,只需要引用jar包,然后添加过滤器即可。但是有些细节还是要注意。
(一)、jar包引用
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>cors-filter</artifactId>
<version>2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.thetransactioncompany/java-property-utils -->
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>java-property-utils</artifactId>
<version>1.9.1</version>
</dependency>
(二)、过滤器实现
web.xml配置:
Java code?
1
2
3
4
5
6
7
8
<filter>
<filter-name>cros</filter-name>
<filter-
`class>ichano.developer.sys.filter.CorsFilter</filter-
class`>
</filter>
<filter-mapping>
<filter-name>cros</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
过滤器中可以配置允许访问的请求方,允许访问的请求方式以及允许通过的请求头信息
Java code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package
ichano.developer.sys.filter;
`/**`
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;
/**
* @ClassName: CorsFilter
* @Description: TODO(设置其他IP地址的机器可以直接访问本项目Url--工具filter)
* @author lizhijun
* @date 2016年8月15日 下午2:25:25
*
*/
public
class
CorsFilter
`extends
OncePerRequestFilter {`
@Override
protected
void
doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
`throws
ServletException, IOException {`
response.addHeader(
`"Access-Control-Allow-Origin",
"");
//为安全起见,可配置允许访问的请求方地址。这里配置成号,是允许所有访问。`
response.addHeader(
`"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE");
//为安全起见,也可配置成只允许POST请求`
response.addHeader(
`"Access-Control-Allow-Headers",
"Content-Type,auth_token");
//这里要注意,auth_token是我自定义的请求头当中带的token,在这里必须添加,否则你永远获取不到。`
response.addHeader(
`"Access-Control-Max-Age",
"1800");
//30 min`
filterChain.doFilter(request, response);
}
}
这里处理了三个坑,
**一是在本地调试的时候可以跨域访问,但是部署到服务器之后,访问失败。解决方法:请求地址后面加上端口号就可以访问。 这个问题就需要在nignx里面进行端口配置。
二是CROS这种传输方式传输的数据到后端接收已不是JSON格式,而是类似于XXX=123&FFFF=384这样的格式,需要对所有请求的入参进行一下转换成json格式。
三是请求头中的自定义字段auth_token在服务器上接收不到,这里需要对ngnix进行配置,允许自定义属性的header配置。
[b]**
Original url: Access
Created at: 2020-09-02 17:59:02
Category: default
Tags: none
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
最新评论