有一個修改密碼的需求岳悟,要求修改完密碼之后判斷當前用戶是否被鎖佃迄,被鎖了的話自動解鎖該用戶。
weblogic控制臺本身有取消用戶鎖定的功能贵少,但是只能一個一個去解鎖呵俏,如下圖所示:
嘗試了2種方式去解鎖。第一種是執(zhí)行java命令滔灶,在集群狀態(tài)下沒成功普碎;另一種是用JMX獲取MBean來解鎖。
一. 使用java命令
這里會用到3條命令:
(1)查找所有Security開頭的MBean資源:
java -cp E:\oracle\Middleware\wlserver_12.1\server\lib\weblogic.jar weblogic.Admin -url 192.168.1.199:7001 -username weblogic -password 11111111 query -pretty -pattern Security:*
打開CMD命令行录平,執(zhí)行該命令后麻车,會顯示MBean Name的列表缀皱,如下圖所示:
紅框圈住的MBeanName就是我要用來解鎖的Name,怎么確定是這個MBean呢动猬?
首先啤斗,oracleRealm是這臺weblogic的默認安全域名,UserLockoutManager是固定名稱赁咙,oracleRealm+UserLockoutManager自然就是我要找的MBean钮莲。
其次,該MBean下列出了一些用戶封鎖管理統(tǒng)計信息彼水,這些屬性值和weblogic控制臺的用戶封鎖管理統(tǒng)計信息是一致的崔拥,如下圖所示:
(2)查詢某個用戶是否被鎖了:
java -cp E:\oracle\Middleware\wlserver_12.1\server\lib\weblogic.jar weblogic.Admin -url 192.168.1.199:7001 -username weblogic -password 11111111 invoke -mbean Security:Name=oracleRealmUserLockoutManager -method isLockedOut poweruniontest
命令執(zhí)行后,如果該用戶被鎖了返回true凤覆,否則返回false(我這里是沒被鎖定的截圖)链瓦,返回結果如下圖所示:
(3)解鎖:
java -cp E:\oracle\Middleware\wlserver_12.1\server\lib\weblogic.jar weblogic.Admin -url 192.168.1.199:7001 -username weblogic -password 11111111 invoke -mbean Security:Name=oracleRealmUserLockoutManager -method clearLockout poweruniontest
命令執(zhí)行后,不管該用戶是否被鎖叛赚,都會返回OK,如果命令執(zhí)行發(fā)生錯誤則會返回failed(未驗證)稽揭,如下圖所示:
試驗結論:試驗證明俺附,在只有一個服務器實例的情況下,這種方法是可以成功解鎖的溪掀;但是事镣,在集群環(huán)境下,比如有一個管理服務器實例(7003)和一個受管服務器實例(8086)揪胃,不能解鎖璃哟,其失敗表現(xiàn)有三:
1.MBean Name的用戶封鎖管理統(tǒng)計信息和weblogic控制臺的信息不符,一些鎖定信息始終為0喊递,如下圖所示:
2.?查詢用戶是否被鎖随闪,結果始終返回false。
3.解鎖骚勘,結果始終返回ok铐伴。
原因不明,如有發(fā)現(xiàn)俏讹,歡迎指正当宴。
二. 使用JMX獲取MBean來解鎖
1.下面是解鎖的封裝類:
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Hashtable;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.naming.Context;
import com.powerunion.oapm.config.ConfigUtil;
public class UnlockWeblogicUser {
?
?public MBeanServerConnection connection;
?public JMXConnector connector;
?public static final ObjectName service;
?public static final String adminServerName;
?
?static{
??try {
???//Type前面沒有空格,若留了空格會報錯:?
? ?//javax.management.InstanceNotFoundException:?
? //com.bea:Name=DomainRuntimeService, T
? //ype=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean
???service = new ObjectName("com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean");
???adminServerName = ConfigUtil.getInstance().getParameter("weblogic.security.server.name");
??} catch (MalformedObjectNameException? e) {
???System.out.println("error:"+e.getMessage());
???throw new AssertionError(e.getMessage());
??}
?}
?
?public boolean invoke(String method, String username) {
??????? String rez = "failed";
??????? int index = 0;
??????? try {
??????? ?System.out.println("About to invoke sericuty method....");
??????????? ObjectName[] serverRT =
??????????????????? (ObjectName[]) connection.getAttribute(service,
??????????????????? "ServerRuntimes");
????????????/*?
???????????? * adminServerName:?在配置文件中配置泽疆,集群中管理服務器
?????????????*的名稱户矢,即負責登錄解鎖等功能的服務器實例的名稱。
???????????? *這里對serverRT進行遍歷殉疼,將管理服務器的索引找出來梯浪。
???????????? */
??????????? for(int i = 0;i < serverRT.length;i++){
??????????? ?if(serverRT[i].toString().contains(adminServerName)){
??????????? ??index = i;
??????????? ??break;
??????????? ?}
??????????? }
??????????? ObjectName ssr =
??????????????????? (ObjectName) connection.getAttribute(serverRT[index],
??????????????????? "ServerSecurityRuntime");
??????????? ObjectName rrm =
??????????????????? (ObjectName) connection.getAttribute(ssr,
??????????????????? "DefaultRealmRuntime");
??????????? ObjectName ulr =
??????????????????? (ObjectName) connection.getAttribute(rrm,
??????????????????? "UserLockoutManagerRuntime");
??????????? if(method.equals("isLockedOut")) {
??????????????? rez =
??????????????????????? connection.invoke(ulr, method,
????????????????????????????????????????? new Object[] {username},
????????????????????????????????????????? new String[] {"java.lang.String"}).
??????????????????????? toString();
??????????? } else if(method.equals("clearLockout")) {
??????????????? connection.invoke(ulr, method,
????????????????????????????????? new Object[] {username},
????????????????????????????????? new String[] {"java.lang.String"});
??????????????? rez = "OK";
??????????? }
??????????? System.out.println("User=" + username + " " + method + "=" + rez);
??????? } catch (MalformedURLException exc) {
??????? ?exc.printStackTrace();
??????? } catch (IOException exc) {
??????? ?exc.printStackTrace();
??????? } catch (Exception e) {
??????? ?e.printStackTrace();
??????? }
??????? try {
??????????? connector.close();
??????? } catch (MalformedURLException exc) {
??????????? System.out.println(exc.getMessage());
??????? } catch (IOException exc) {
??????????? System.out.println(exc.getMessage());
??????? } catch (Exception e) {
??????????? System.out.println(e.getMessage());
??????? }
??????? if (rez.trim().equals("false") || rez.trim().equals("failed")) {
??????????? return false;
??????? } else {
??????????? return true;
??????? }
??? }
?
?public void initConnection(String hostname, String portString,String username, String password) throws IOException,MalformedURLException{
??String protocol = "t3";
??Integer portInteger = Integer.valueOf(portString);
??int port = portInteger.intValue();
??String jndiroot = "/jndi/";
??String mserver = "weblogic.management.mbeanservers.domainruntime";
??JMXServiceURL serviceURL = new JMXServiceURL(protocol, hostname, port, jndiroot + mserver);
??Hashtable<String, String> h = new Hashtable<String, String>();
??h.put(Context.SECURITY_PRINCIPAL, username);
??h.put(Context.SECURITY_CREDENTIALS, password);
??h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, "weblogic.management.remote");
??connector = JMXConnectorFactory.connect(serviceURL, h);
??connection = connector.getMBeanServerConnection();
??System.out.println("connected!");
?}
}
2.下面是調用的類:
//下面的ip捌年、port:管理服務器的ip和端口;username驱证、password:weblogic管理員的用戶名和密碼延窜。