Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.alogic.bearer.BearerHandler Maven / Gradle / Ivy
package com.alogic.bearer;
import com.alogic.json.JsonFactory;
import com.alogic.xscript.Logiclet;
import com.alogic.xscript.LogicletContext;
import com.alogic.xscript.Script;
import com.alogic.xscript.doc.XsObject;
import com.alogic.xscript.doc.json.JsonObject;
import com.anysoft.util.*;
import com.anysoft.util.resource.ResourceFactory;
import com.anysoft.webloader.HttpClientTool;
import com.anysoft.webloader.ServletConfigProperties;
import com.anysoft.webloader.ServletHandler;
import com.logicbus.backend.Context;
import com.logicbus.backend.bizlog.BizLog;
import com.logicbus.backend.server.http.HttpContext;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Bearer Handler
*
* @since 1.6.14.13 [2021708 duanyy]
*
* @version 1.6.15.2 [20211103 duanyy]
* - 在doAuth时注入service变量;
*/
public class BearerHandler implements ServletHandler, XMLConfigurable, Configurable,BearerConstants {
/**
* a logger of slf4j
*/
protected final static Logger LOG = LoggerFactory.getLogger(BearerHandler.class);
/**
* 缺省配置文件
*/
protected static final String DEFAULT = "java:///com/alogic/bearer/default.xml#App";
/**
* command的前缀
*/
protected String cmdPrefix = "/auth";
/**
* 获取token的地址
*/
protected String realm = "/auth/token";
protected String realmMode = "link";
protected String service = "self";
/**
* 编码
*/
protected String encoding = "utf-8";
/**
* 验证当前token及权限
*/
protected Logiclet onAuth = null;
/**
* 获取token
*/
protected Logiclet onToken = null;
protected HttpClientTool httpClientTool = null;
protected static Pattern bearerPattern = Pattern.compile("^Bearer (.+)$");
protected static Pattern basicPattern = Pattern.compile("^Basic (.+)$");
protected static Pattern realmPattern = Pattern.compile("^\\[(\\w*)\\](.+)$");
protected String contentType = "application/json;charset=utf-8";
protected JsonFactory jsonFactory = Settings.getToolkit(JsonFactory.class);
public void bizlog(String service,String clientIp,long time,long duration,String url,boolean error,String reason){
BizLog.log(KeyGen.uuid(8,0,15),service,clientIp,error?CODE_ERR:CODE_OK,reason,time,duration,url);
}
@Override
public void configure(Properties p) {
cmdPrefix = PropertiesConstants.getString(p, "cmdPrefix",cmdPrefix);
encoding = PropertiesConstants.getString(p, "encoding",encoding);
service = PropertiesConstants.getString(p,"service",service);
httpClientTool = Settings.getToolkit(HttpClientTool.class);
realm = PropertiesConstants.getString(p,"realm",realm);
Matcher matcher = realmPattern.matcher(realm);
if (matcher.find()){
this.realmMode = matcher.group(1);
this.realm = matcher.group(2);
}
}
@Override
public void configure(Element e, Properties p) {
Properties props = new XmlElementProperties(e,p);
configure(props);
Element elem = XmlTools.getFirstElementByPath(e, "on-auth");
if (elem != null){
onAuth = Script.create(elem, props);
}
elem = XmlTools.getFirstElementByPath(e, "on-token");
if (elem != null){
onToken = Script.create(elem, props);
}
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
ServletConfigProperties props = new ServletConfigProperties(servletConfig);
String master = PropertiesConstants.getString(props, "bearer.server.master", DEFAULT);
String secondary = PropertiesConstants.getString(props, "bearer.server.secondary", DEFAULT);
ResourceFactory rf = Settings.getResourceFactory();
InputStream in = null;
try {
in = rf.load(master, secondary, null);
Document doc = XmlTools.loadFromInputStream(in);
if (doc != null){
configure(doc.getDocumentElement(), props);
}
}catch (Exception ex){
LOG.error("Can not init bearer handler with file : " + master);
}finally{
IOTools.close(in);
}
}
@Override
public void doService(HttpServletRequest httpReq, HttpServletResponse httpResp, String method) throws ServletException, IOException {
try {
String cmd = getCommand(httpReq.getContextPath(),httpReq.getRequestURI());
if (StringUtils.isNotEmpty(cmd)){
if (cmd.startsWith("/token")){
doToken(onToken,httpReq,httpResp);
return;
}
}
doAuth(onAuth,httpReq,httpResp);
}catch (BaseException ex){
httpClientTool.sendError(httpResp,E404,String.format("%s:%s",ex.getCode(),ex.getMessage()));
}
}
protected void doAuth(Logiclet handler,HttpServletRequest httpReq, HttpServletResponse httpResp) {
if (handler == null){
throw new BaseException("core.e1000","Handler on-auth is not defined");
}
String token = getBearerToken(httpReq,TOKEN_NULL);
Context ctx = new HttpContext(httpReq,httpResp,encoding);
LogicletContext logicletContext = new Context.ServantLogicletContext(ctx);
long start = System.nanoTime();
String clientIp = httpClientTool.getClientIp(httpReq);
try {
logicletContext.SetValue("$service", "/bearer/auth");
logicletContext.SetValue("$clientIp",clientIp);
logicletContext.SetValue("$token",token);
logicletContext.SetValue("service",service);
XsObject doc = new JsonObject("root",new HashMap());
handler.execute(doc,doc, logicletContext, null);
int status = PropertiesConstants.getInt(logicletContext,"$status",E200);
String provider = PropertiesConstants.getString(logicletContext,"service",service);
httpClientTool.setStatus(httpResp,status);
if (status != E200){
httpClientTool.setResponseHeader(httpResp,HEAD_WWW_AUTHENTICATE,
String.format(BEARER,getRealm(httpReq), provider));
}
OutputStream out = null;
try {
String data = jsonFactory.toJsonString(doc.getContent());
ctx.setResponseContentType(contentType);
out = ctx.getOutputStream();
byte [] bytes = data.getBytes(ctx.getEncoding());
ctx.setResponseContentLength(bytes.length);
Context.writeToOutpuStream(out, bytes);
out.flush();
} catch (Exception ex) {
LOG.error("Error when writing data to outputstream",ex);
}finally {
IOTools.close(out);
}
}finally{
bizlog("/bearer/auth",clientIp,System.currentTimeMillis(),
System.nanoTime() - start,httpReq.getRequestURL().toString(),false,"");
}
}
protected String getRealm(HttpServletRequest httpReq) {
if (realmMode.equalsIgnoreCase("local")){
return httpClientTool.getContextBase(httpReq) + realm;
}else {
return realm;
}
}
protected String getBearerToken(HttpServletRequest httpReq, String dft) {
String header = httpClientTool.getRequestHeader(httpReq,HEAD_AUTHORIZATION);
if (StringUtils.isEmpty(header)){
return dft;
}
Matcher matcher = bearerPattern.matcher(header);
if (matcher.find()){
return matcher.group(1);
}else{
return dft;
}
}
protected String getBasicAuth(HttpServletRequest httpReq, String dft) {
String header = httpClientTool.getRequestHeader(httpReq,HEAD_AUTHORIZATION);
if (StringUtils.isEmpty(header)){
return dft;
}
Matcher matcher = basicPattern.matcher(header);
if (matcher.find()){
return matcher.group(1);
}else{
return dft;
}
}
protected void doToken(Logiclet handler,HttpServletRequest httpReq, HttpServletResponse httpResp) {
if (handler == null){
throw new BaseException("core.e1000","Handler on-token is not defined");
}
String basicAuth = getBasicAuth(httpReq,"0");
Context ctx = new HttpContext(httpReq,httpResp,encoding);
LogicletContext logicletContext = new Context.ServantLogicletContext(ctx);
long start = System.nanoTime();
String clientIp = httpClientTool.getClientIp(httpReq);
try {
logicletContext.SetValue("$service", "/bearer/token");
logicletContext.SetValue("$clientIp",clientIp);
logicletContext.SetValue("$auth",basicAuth);
XsObject doc = new JsonObject("root",new HashMap());
handler.execute(doc,doc, logicletContext, null);
int status = PropertiesConstants.getInt(logicletContext,"$status",E200);
httpClientTool.setStatus(httpResp,status);
OutputStream out = null;
try {
String data = jsonFactory.toJsonString(doc.getContent());
ctx.setResponseContentType(contentType);
out = ctx.getOutputStream();
byte [] bytes = data.getBytes(ctx.getEncoding());
ctx.setResponseContentLength(bytes.length);
Context.writeToOutpuStream(out, bytes);
out.flush();
} catch (Exception ex) {
LOG.error("Error when writing data to outputstream",ex);
}finally {
IOTools.close(out);
}
}finally{
bizlog("/bearer/token",clientIp,System.currentTimeMillis(),
System.nanoTime() - start,httpReq.getRequestURL().toString(),false,"");
}
}
@Override
public void destroy() {
}
protected String getCommand(String contextPath,String uri){
String prefix = contextPath + this.cmdPrefix;
if (uri.startsWith(prefix)){
return uri.substring(prefix.length());
}else{
return "";
}
}
protected String getParameter(HttpServletRequest request,String id,String dftValue){
String value = request.getParameter(id);
return StringUtils.isEmpty(value)?dftValue:value;
}
}