统一认证相关知识

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();
        } 
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值