转:

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

l

为Druid监控配置访问权限(配置访问监控信息的用户与密码)
2014-09-26 09:21:48         来源:renfufei的专栏  
收藏   我要投稿
 

Druid是一个强大的新兴数据库连接池,兼容DBCP,是阿里巴巴做的开源项目.

不仅提供了强悍的数据源实现,还内置了一个比较靠谱的监控组件

GitHub项目主页: https://github.com/alibaba/druid

QQ群: 点击链接加入群【阿里开源技术交流】

演示地址: https://cncounter.duapp.com/druid/index.html

常见问题回答请参考: https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98

一篇CSDN对Druid的介绍 druid简单教程

因为想要监控数据,又不愿意谁都可以访问,所以想要配置个密码.在开源群里一问,就知道原来内部已经有实现了.

先贴完成后的代码:

web.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 <! -- Druid,监控数据库,以及WEB访问连接信息 --> <! -- 参考: https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_%E9%85%8D%E7%BD%AEWebStatFilter --> <filter>      <filter- name >DruidWebStatFilter</filter- name >      <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>      <init-param>          <param- name >exclusions</param- name >          <param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,*.jsp,/druid/*,/download/*</param-value>      </init-param>      <init-param>          <param- name >sessionStatMaxCount</param- name >          <param-value>2000</param-value>      </init-param>      <init-param>          <param- name >sessionStatEnable</param- name >          <param-value> true </param-value>      </init-param>      <init-param>          <param- name >principalSessionName</param- name >          <param-value>session_user_key</param-value>      </init-param>      <init-param>          <param- name >profileEnable</param- name >          <param-value> true </param-value>      </init-param> </filter> <filter-mapping>      <filter- name >DruidWebStatFilter</filter- name >      <url-pattern>/*</url-pattern> </filter-mapping> <! -- 配置 Druid 监控信息显示页面 --> <servlet>      <servlet- name >DruidStatView</servlet- name >      <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>      <init-param>          <! -- 允许清空统计数据 -->          <param- name >resetEnable</param- name >          <param-value> true </param-value>      </init-param>      <init-param>          <! -- 用户名 -->          <param- name >loginUsername</param- name >          <param-value>druid</param-value>      </init-param>      <init-param>          <! -- 密码 -->          <param- name >loginPassword</param- name >          <param-value>druid</param-value>      </init-param> </servlet> <servlet-mapping>      <servlet- name >DruidStatView</servlet- name >      <url-pattern>/druid/*</url-pattern> </servlet-mapping>

首先,因为使用的是 MAVEN, 所以查看源码时maven会自动帮你下载. 我们在 web.xml 中点击 com.alibaba.druid.support.http.StatViewServlet 进入class文件,等一会源码下载好就可以查看. 发现有类似下面这样的代码:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class StatViewServlet extends ResourceSerlvet {        private final static Log      LOG                     = LogFactory.getLog(StatViewServlet.class);        private static final long     serialVersionUID        = 1L;        public static final String    PARAM_NAME_RESET_ENABLE = "resetEnable" ;        public static final String    PARAM_NAME_JMX_URL      = "jmxUrl" ;      public static final String    PARAM_NAME_JMX_USERNAME = "jmxUsername" ;      public static final String    PARAM_NAME_JMX_PASSWORD = "jmxPassword" ;        private DruidStatService      statService             = DruidStatService.getInstance();        /** web.xml中配置的jmx的连接地址 */      private String                jmxUrl                  = null ;      /** web.xml中配置的jmx的用户名 */      private String                jmxUsername             = null ;      /** web.xml中配置的jmx的密码 */      private String                jmxPassword             = null ; .........
StatViewServlet extends ResourceSerlvet

而在其中的 jmxUrl、jmxUsername 和 jmxPassword 很显然是连接远程 JMX时使用的,那么我就想着去看看父类: com.alibaba.druid.support.http.ResourceSerlvet

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @SuppressWarnings( "serial" ) public abstract class ResourceSerlvet extends HttpServlet {        private final static Log   LOG                 = LogFactory.getLog(ResourceSerlvet.class);        public static final String SESSION_USER_KEY    = "druid-user" ;      public static final String PARAM_NAME_USERNAME = "loginUsername" ;      public static final String PARAM_NAME_PASSWORD = "loginPassword" ;      public static final String PARAM_NAME_ALLOW    = "allow" ;      public static final String PARAM_NAME_DENY     = "deny" ;      public static final String PARAM_REMOTE_ADDR   = "remoteAddress" ;        protected String           username            = null ;      protected String           password            = null ; .......... 
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {      ......      if (isRequireAuth() //          && !ContainsUser(request)//          && !( "/login.html" .equals(path) //               || path.startsWith( "/css" )//               || path.startsWith( "/js" ) //          || path.startsWith( "/img" ))) {          if (contextPath == null || contextPath.equals( "" ) || contextPath.equals( "/" )) {              response.sendRedirect( "/druid/login.html" );          } else {              if ( "" .equals(path)) {                  response.sendRedirect( "druid/login.html" );              } else {                  response.sendRedirect( "login.html" );              }          }          return ;      } ......
isRequireAuth() 方法,看着像是判断是否需要授权验证,于是进去看 ?
1 2 3 public boolean isRequireAuth() {      return this.username != null ; }

那现在知道是 username 在作怪,也设置了,但是没有起作用,于是搜索 username ,

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public void init() throws ServletException {      initAuthEnv(); }   private void initAuthEnv() {      String paramUserName = getInitParameter(PARAM_NAME_USERNAME);      if (!StringUtils.isEmpty(paramUserName)) {          this.username = paramUserName;      }        String paramPassword = getInitParameter(PARAM_NAME_PASSWORD);      if (!StringUtils.isEmpty(paramPassword)) {          this. password = paramPassword;      }    ......
然后发现了初始化验证环境时使用了PARAM_NAME_USERNAME这个参数,顺便的学习了一个新API: getInitParameter 方法获取 Servlet的初始化参数, 是HttpServlet的父类 GenericServlet 类提供的:
String paramUserName = getInitParameter(PARAM_NAME_USERNAME);
那么很简单,找到 PARAM_NAME_USERNAME 即可:
public static final String PARAM_NAME_USERNAME = "loginUsername"; public static final String PARAM_NAME_PASSWORD = "loginPassword";
于是在 web.xml 中换上,OK,成功进行了拦截.

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄