access token
accesstoken是Windows操作系统安全性的一个概念。一个访问令牌包含了此登陆会话的安全信息。当用户登陆时,系统创建一个访问令牌,然后以该用户身份运行的的所有进程都拥有该令牌的一个拷贝。
该令牌唯一表示该用户、用户的组和用户的特权。系统使用令牌控制用户可以访问哪些安全对象,并控制用户执行相关系统操作的能力。有两种令牌:主令牌和模拟的令牌。主令牌是与进程相关的;模拟的令牌是与模拟令牌的线程相关的。
ServletRequest
ServletRequest由Servlet容器来管理,当客户请求到来时,容器(运行servelet的程序)创建一个ServletRequest对象,封装请求数据,同时创建一个ServletResponse对象,封装响应数据。这两个对象将被容器作为service()方法的参数传递给Servlet,Serlvet利用ServletRequest对象获取客户端发来的请求数据,利用ServletResponse对象发送响应数据。
getRequestDispatcher()与sendRedirect()(request、 传值方式)
(1)request.getRequestDispatcher()是请求转发,前后页面共享一个request ;这个是在服务端运行的,对浏览器来说是透明的。
redirect 方式
response.sendRedirect(“/a.jsp”);
页面的路径是相对路径。sendRedirect可以将页面跳转到任何页面,不一定局限于本web应用中,如:
response.sendRedirect(“URL”);
跳转后浏览器地址栏变化。
这种方式要传值出去的话,只能在url中带parameter或者放在session中,无法使用request.setAttribute来
传递。所以该方式只适用于无传值跳转(2)response.sendRedirect()是重新定向,前后页面不是一个request。而这个是在浏览器端运行的。
forward方式 request.getRequestDispatcher(“/路径(可以是jsp路径也可以是servlet)”)
.forward(request, response); 如:
request.getRequestDispatcher(“/2.jsp)”) .forward(request, response);
request.getRequestDispatcher(“/servlet/HomeServlet)”)
.forward(request, response);
Servlet页面跳转的路径是相对路径。forward方式只能跳转到本web应用中的页面上。 跳转后浏览器地址栏不会变化。
使用这种方式跳转,传值可以使用三种方法:url中带parameter,session,request.setAttribute
在url中加入参数的例子如下:
private void gotoLogin(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
try {
String state = UUID.randomUUID().toString().replace("-", "");//state参数防止csrf攻击
HttpSession session = request.getSession();
session.setAttribute("state", state);
StringBuffer sbuffer = new StringBuffer(); //缓冲区
sbuffer.append(loginUrl);
if(loginUrl.contains("?")){
sbuffer.append("&");
}else{
sbuffer.append("?");
}
sbuffer.append("appId=").append(clientId);
sbuffer.append("&response_type=").append(authcCodeParam);
sbuffer.append("&redirect_uri=").append(URLEncoder.encode(redirect_uri, "utf-8"));
sbuffer.append("&scope=").append(scope);
sbuffer.append("&state=").append(state);
response.sendRedirect(sbuffer.toString()); ///只能在url中带parameter或者放在session中,
} catch (Exception e) {
e.printStackTrace();
}
}
JSONObject介绍
JSONObject-lib包是一个beans,collections,maps,java arrays和xml和JSON互相转换的包。
fromBean(Object bean);静态方法,通过一个pojo对象创建一个JSONObject对象
fromJSONObject(JSONObject
object);静态方法,通过另外一个JSONObject对象构造一个JSONObject对象
fromJSONString(JSONString string);静态方法,通过一个JSONString创建一个JSONObject对象
toString();把JSONObject对象转换为json格式的字符串
iterator();返回一个Iterator对象来遍历元素
Filter(Filter链,在web.xml中哪个先配置,哪个就先调用。在filter中也可以配置一些初始化参数。)
http://blog.csdn.net/liuwenbo0920/article/details/7290386
Java中的Filter并不是一个标准的Servlet,它不能处理用户请求,也不能对客户端生成响应。主要用于对HttpServletRequest进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链。
Filter有如下几个用处:
l在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest。
l根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据。
l在HttpServletResponse到达客户端之前,拦截HttpServletResponse。
l根据需要检查HttpServletResponse,可以修改HttpServletResponse头和数据。 Filter有如下几个种类:
l用户授权的Filter: Filter负责检查用户请求,根据请求过滤用户非法请求。 l日志Filter:详细记录某些特殊的用户请求。
l负责解码的Filter:包括对非标准编码的请求解码。 l能改变XML内容的XSLTFilter等。
一个Filter可负责拦截多个请求或响应:一个请求或响应也可被多个请求拦截。 创建一个Filter只需两个步骤:
(1)创建Filter处理类: (2)在web.xml文件中配置Filter。
附上段
package com.siant.filter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.siant.web.entity.AccessToken;
import com.siant.web.util.HttpRequestClient;
import com.siant.web.util.HttpUtil;
public class OAuthFilter implements Filter {
private static String filtFlag;
//oauth2 authc code授权码
private String authcCodeParam = "code";
//应用系统id,身份认证服务系统分配
private String clientId;
//应用系统secret,身份认证服务系统分配
private String clientSecrect;
private String scope;//获取资源作用域,多个可用;分隔(userInfo只获取用户资源)
private String grant_type = "authorization_code";//填写authorization_code就可以了
private String redirect_uri;//应用系统 回调地址
private String loginUrl;//通过重定向到认证服务获取
private String userInfoUrl;//获取用户信息API接口地址
private String accessTokenUrl;//获取令牌API接口地址
private String errorPage;
private List<String> noauthurl=new ArrayList<String>();
private String httpProtocol;
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
try {
boolean result = false;
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
if(filtFlag!=null && filtFlag.equals("false")){
chain.doFilter(request, response);
return;
}
HttpSession session = request.getSession();
String requesturi = request.getRequestURI();
if(noauthurl != null && noauthurl.size() != 0){
for(int i=0;i<noauthurl.size();i++) {
if (requesturi.contains(noauthurl.get(i))) {
chain.doFilter(request, response);
return;
}
}
}
//从session获取access_token对象
AccessToken token = (AccessToken) session.getAttribute("accesstoken");
if(token==null){
//从url获取code
String code = request.getParameter(authcCodeParam);
if(code != null && !"".equals(code)){
//从url获取ȡstate,与session中state比较防止csrf
String state = request.getParameter("state");
String cstate = (String) session.getAttribute("state");
if (state==null || (cstate != null && !cstate.equals(state))) {
//可能是csrf
Map map = new HashMap();
map.put("errcode", "40011");
map.put("msg", "state不一致");
request.setAttribute("result", map);
request.getRequestDispatcher(errorPage).forward(request, response);
// response.sendRedirect("error.jsp");
return;
}
//获取accesstoken(json格式)
// String accesstoken = HttpRequestClient.sendPost(accessTokenUrl, "appId="+clientId+"&secret="+clientSecrect+"&code="+code+"&grant_type="+grant_type);
String accesstoken ="";
if("0".equals(httpProtocol)){
accesstoken=HttpRequestClient.sendPost(accessTokenUrl, "appId="+clientId+"&secret="+clientSecrect+"&code="+code+"&grant_type="+grant_type);
}else{
accesstoken = HttpUtil.getMethod(accessTokenUrl, "appId="+clientId+"&secret="+clientSecrect+"&code="+code+"&grant_type="+grant_type);
System.out.println("accesstoken:"+accesstoken);
}
JSONObject tokenjson = JSONObject.fromObject(accesstoken);
result = tokenjson.getBoolean("result");
if(!result){
request.setAttribute("result", tokenjson);
request.getRequestDispatcher(errorPage).forward(request, response);
return;
}
token = parseAccesstoken(accesstoken);
//将token对象保存到session
session.setAttribute("accesstoken", token);
afterAccessToken(request, response, token, chain);
// chain.doFilter(request, response);
return;
}else{
//重定向身份认证系统
gotoLogin(request, response);
return;
}
}else{
afterAccessToken(request, response, token, chain);
// chain.doFilter(request, response);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void init(FilterConfig filterConfig) throws ServletException {
filtFlag = filterConfig.getInitParameter("filtFlag");
InputStream in = null;
String spConfig = filterConfig.getInitParameter("SPConfig");
if (spConfig == null) {
throw new ServletException("Config file path not be set");
}
ServletContext ctx = filterConfig.getServletContext();
in = ctx.getResourceAsStream(spConfig);
SAXReader reader = new SAXReader();
Document doc = null;
try {
doc = reader.read(in);
Element root = doc.getRootElement();
clientId= root.element("AppId").getText();
clientSecrect= root.element("AppSecret").getText();
scope= root.element("Scope").getText();
userInfoUrl= root.element("UserInfoUrl").getText();
redirect_uri= root.element("RedirectUri").getText();
loginUrl= root.element("LoginURL").getText();
accessTokenUrl= root.element("AccessTokenUrl").getText();
userInfoUrl= root.element("UserInfoUrl").getText();
errorPage = root.element("ErrorPage").getText();
httpProtocol = root.element("HttpProtocol").getText();
Element NotAuthenticate = root.element("NotAuthenticate");
List<Element> obj = NotAuthenticate.elements("URI");
if (obj != null && obj.size() != 0 ) {
for (int i = 0; i < obj.size(); i++) {
if (obj.get(i).getText() != null
&& !"".equals(obj.get(i).getText())) {
noauthurl.add(obj.get(i).getText());
}
}
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
private void gotoLogin(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
try {
String state = UUID.randomUUID().toString().replace("-", "");//state参数防止csrf攻击
HttpSession session = request.getSession();
session.setAttribute("state", state);
StringBuffer sbuffer = new StringBuffer();
sbuffer.append(loginUrl);
if(loginUrl.contains("?")){
sbuffer.append("&");
}else{
sbuffer.append("?");
}
sbuffer.append("appId=").append(clientId);
sbuffer.append("&response_type=").append(authcCodeParam);
sbuffer.append("&redirect_uri=").append(URLEncoder.encode(redirect_uri, "utf-8"));
sbuffer.append("&scope=").append(scope);
sbuffer.append("&state=").append(state);
response.sendRedirect(sbuffer.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
public AccessToken parseAccesstoken(String accesstoken){
JSONObject json = JSONObject.fromObject(accesstoken);
AccessToken tokenJson = new AccessToken();
tokenJson.setAccess_token(json.get("access_token").toString());
tokenJson.setCreatetime(new Date());
tokenJson.setExpires_in(Long.valueOf(json.getLong("expires_in")));
tokenJson.setOpenid(json.get("openid").toString());
tokenJson.setRefresh_token("");
tokenJson.setScope(json.getString("scope"));
tokenJson.setAuthmode(json.getString("authmode"));
return tokenJson;
}
public boolean checkAccesstoken(AccessToken accesstoken){
Date createtime = accesstoken.getCreatetime();
Date now = new Date();
Date afterDate = new Date(createtime.getTime() + accesstoken.getExpires_in()*1000);
if(afterDate.after(now)){
return true;
}
return false;
}
public void afterAccessToken(HttpServletRequest request, HttpServletResponse response,AccessToken token,FilterChain chain){
HttpSession session = request.getSession();
try {
//检查token是否在有效期内
if(checkAccesstoken(token)){
// JSONObject jsonObject = (JSONObject) session.getAttribute("userinfojson");
// if(jsonObject != null){
// chain.doFilter(request, response);
// return;
// }
// //获取用户信息
// String userinfojson = "";
// if("0".equals(httpProtocol)){
// userinfojson = HttpRequestClient.sendPost(userInfoUrl, "access_token="+token.getAccess_token()+"&scope="+token.getScope());
// }else{
// userinfojson = HttpUtil.getMethod(userInfoUrl, "access_token="+token.getAccess_token()+"&scope="+token.getScope());
// }
// System.out.println("userinfojson:"+userinfojson);
// if(userinfojson != null && !"".equals(userinfojson)){
// JSONObject json = JSONObject.fromObject(userinfojson);
// //返回结果json类型
// boolean result = json.getBoolean("result");
//
// if(result){
// session.setAttribute("userinfojson", json);
chain.doFilter(request, response);
// }else{
// request.setAttribute("result", json);
// request.getRequestDispatcher(errorPage).forward(request, response);
response.sendRedirect("error.jsp?errorcode="+json.get("errcode"));
// return;
// }
// }
}else{
//重定向身份认证系统
gotoLogin(request, response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}