Does anyone know how to list all the weblogic users in java?
For instance, there is 5 users in security realm, and I want to get all of them. How do I do?
It's pretty easy. For future reference, if you want to look up something like "how do I do X with weblogic and Java..." use JMX in your google search. Here is an example from weblogic wonders. Note you will need to change your URL and user/password in the code:
import javax.naming.*;
import javax.management.MBeanInfo;
import weblogic.jndi.Environment;
import weblogic.management.runtime.ServerRuntimeMBean;
import weblogic.security.providers.authentication.DefaultAuthenticatorMBean;
import weblogic.management.security.authentication.UserReaderMBean;
import weblogic.management.security.authentication.GroupReaderMBean;
import weblogic.management.MBeanHome;
import weblogic.management.WebLogicMBean;
import weblogic.management.tools.Info;
import weblogic.management.Helper;
import weblogic.management.security.authentication.*;
public class ListUsersAndGroups
{
public static void main(String[] args)
{
MBeanHome home = null;
try
{
Environment env = new Environment();
env.setProviderUrl(“t3://localhost:7001?);
env.setSecurityPrincipal(“weblogic”);
env.setSecurityCredentials(“weblogic”);
Context ctx = env.getInitialContext();
home = (MBeanHome)ctx.lookup(“weblogic.management.adminhome”);
weblogic.management.security.RealmMBean rmBean =
home.getActiveDomain().getSecurityConfiguration().getDefaultRealm();
AuthenticationProviderMBean[] authenticationBeans =
rmBean.getAuthenticationProviders();
DefaultAuthenticatorMBean defaultAuthenticationMBean =
(DefaultAuthenticatorMBean)authenticationBeans[0];
UserReaderMBean userReaderMBean =
(UserReaderMBean)defaultAuthenticationMBean;
String userCurName = userReaderMBean.listUsers(“*”, 100);
while (userReaderMBean.haveCurrent(userCurName) )
{
String user = userReaderMBean.getCurrentName(userCurName);
System.out.println(“\n User: ” + user);
userReaderMBean.advance(userCurName);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
EDIT
There isn't really any way around have to know the user/password to look up the users. You can do it via WLST scripting as well if that sounds like a better option. See an example here.
Last but not least, you could set anonymous bind on the embedded ldap for Weblogic to allow anonymous lookups (which is generally not recommended for production). This sample shows how to do it with an external client: Weblogic w/External Ldap Client
The key settings are:
Your Domain -> Security -> Embedded LDAP
Change the (default generated) password (for example: weblogic)
Enable “Anonymous Bind Allowed”
Related
Is there a way to use the azure-notificationhubs-java-backend library behind a corporate proxy with authentication?
I will be using the library under an application server (JBoss 6), so I'd like to avoid the classic Java system properties approach (https.proxyHost, https.proxyPort, etc.), since it affects the whole JVM.
Thanks in advance.
Regards,
Nuno Guerreiro
I managed to solve this problem. I'm posting the solution here, just in case anyone needs it ;).
In my specific case, I use a Windows 8 PC and my proxy requires Windows (NTLM) authentication. The code below uses NTLM integrated authentication, i.e., no username and password need to be explicitly set, since the security credentials of the currently logged-on user will be used.
import com.windowsazure.messaging.*;
import java.util.concurrent.Future;
import org.apache.http.auth.AuthSchemeProvider;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.HttpHost;
import org.apache.http.impl.auth.BasicSchemeFactory;
import org.apache.http.impl.auth.DigestSchemeFactory;
import org.apache.http.impl.auth.win.WindowsCredentialsProvider;
import org.apache.http.impl.auth.win.WindowsNTLMSchemeFactory;
import org.apache.http.impl.auth.win.WindowsNegotiateSchemeFactory;
import org.apache.http.impl.client.SystemDefaultCredentialsProvider;
import org.apache.http.impl.client.WinHttpClients;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
public class Test9 {
private static HttpAsyncClientBuilder createAsyncBuilderWithProxy(String proxyHost, int proxyPort) {
if (WinHttpClients.isWinAuthAvailable()) {
final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
.register(AuthSchemes.BASIC, new BasicSchemeFactory())
.register(AuthSchemes.DIGEST, new DigestSchemeFactory())
.register(AuthSchemes.NTLM, new WindowsNTLMSchemeFactory(null))
.register(AuthSchemes.SPNEGO, new WindowsNegotiateSchemeFactory(null))
.build();
final CredentialsProvider credsProvider = new WindowsCredentialsProvider(new SystemDefaultCredentialsProvider());
return HttpAsyncClientBuilder.create()
.setDefaultCredentialsProvider(credsProvider)
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
.setProxy(new HttpHost(proxyHost, proxyPort));
} else {
return HttpAsyncClientBuilder.create().setProxy(new HttpHost(proxyHost, proxyPort));
}
}
public static void main(String[] args) throws Exception {
if(args.length < 4) {
System.err.println("syntax: java Test9 <hub connection string> <hub name> <push notification address> <push message>");
} else {
String hubConnectionString = args[0];
String hubName = args[1];
String pushNotificationAddress = args[2];
String pushMessage = args[3];
CloseableHttpAsyncClient httpClient = createAsyncBuilderWithProxy("proxy.corporate.com", 8080).build();
httpClient.start();
HttpClientManager.setHttpAsyncClient(httpClient);
NotificationHub hub = new NotificationHub(hubConnectionString, hubName);
Notification notification = Notification.createGcmNotifiation(pushMessage);
hub.sendDirectNotification(notification, pushNotificationAddress);
System.out.println("Notification sent!");
httpClient.close();
}
}
}
Based on the azure-notificationhubs-java-backend library without the proxy setting apis, there seems to be not any way to use it via proxy with authentication without any affection for the whole JVM of your JBoss.
So per my experience, the only way is creating a new instance of JBoss server using Java system properties for proxy settings to run your Azure notificationhubs java backend and communicate with your main application on the other JBoss server instance via the RPC ways like REST API, WS* API, etc.
Hope it helps.
I am writing a back-end process in Java that will impersonate a user and add/remove documents on their Google Drive.
The server account seems to authenticate correctly but when I try to impersonate a user, I get a 401 Unauthorized error. Please see below for details.
Configuration
I have configured the server account as follows:
Created a project under Google APIs and enabled Google Drive API
Created a service account called anothertest#yyyyyyyyy.iam.gserviceaccount.com, set the role as Service Account Actor and given it domain-wide delegation. It has Client ID 110xxxxxxxxx342
I have download the P12 key file
I have configured the domain using the Manage API client access screen to authorize 110xxxxxxxxx342 to have the scope: https://www.googleapis.com/auth/drive.
Google Support have looked at my configuration and have given it the thumbs up.
My code then looks as follows:
package com.dcm.sharingdocuments;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
import com.google.api.client.auth.oauth2.TokenErrorResponse;
import com.google.api.client.auth.oauth2.TokenResponseException;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.FileList;
public class SharingDocumentsTest3 {
private static final String SERVICE_ACCOUNT_EMAIL = " anothertest#yyyyyyyyy.iam.gserviceaccount.com";
public static Drive getDriveService(String userEmail) throws Exception {
File keyFile = new File("E:\\Projects\\Workspace\\Sharing Documents\\authentication\\AnotherTestKeyFile.p12");
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
List<String> SCOPES = Arrays.asList(DriveScopes.DRIVE_METADATA_READONLY);
GoogleCredential credential = null;
if (userEmail == null) {
credential = new GoogleCredential.Builder().setTransport(httpTransport).setJsonFactory(jsonFactory)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL).setServiceAccountScopes(SCOPES)
.setServiceAccountPrivateKeyFromP12File(keyFile).build();
credential.refreshToken();
} else {
credential = new GoogleCredential.Builder().setTransport(httpTransport).setJsonFactory(jsonFactory)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL).setServiceAccountScopes(SCOPES)
.setServiceAccountPrivateKeyFromP12File(keyFile).setServiceAccountUser(userEmail).build();
credential.refreshToken();
}
Drive service = new Drive.Builder(httpTransport, jsonFactory, null).setHttpRequestInitializer(credential)
.build();
return service;
}
public static void main(String[] args) {
SharingDocumentsTest3 sdt3 = new SharingDocumentsTest3();
sdt3.execute();
}
private void execute() {
try {
Drive service = getDriveService(null);
Drive services = getDriveService("anzzzze#zzzzz.me.uk");
displayFiles(services);
} catch (Exception e) {
e.printStackTrace();
}
}
private void displayFiles(Drive service) throws Exception {
FileList result = service.files().list().setPageSize(10).execute();
List<com.google.api.services.drive.model.File> files = result.getFiles();
if (files == null || files.size() == 0) {
System.out.println("No files found.");
} else {
System.out.println("Files:");
for (com.google.api.services.drive.model.File file : files) {
Set<Entry<String, Object>> entries = file.entrySet();
Iterator<Entry<String, Object>> it = entries.iterator();
while (it.hasNext()) {
Entry<String, Object> entry = it.next();
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof String) {
System.out.println("\tKey = " + key + ", Value = " + (String) value);
} else {
System.out.println("\tKey = " + key + ", Value = " + value.toString());
}
}
System.out.printf("%s (%s)\n", file.getName(), file.getId());
}
}
}
}
When I run the code as is above, I get the error:
Mar 29, 2017 9:55:27 AM com.google.api.client.googleapis.services.AbstractGoogleClient <init>
WARNING: Application name is not set. Call Builder#setApplicationName.
com.google.api.client.auth.oauth2.TokenResponseException: 401 Unauthorized
at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:105)
at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:287)
at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:307)
at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java:384)
at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:489)
at com.dcm.sharingdocuments.SharingDocumentsTest3.getDriveService(SharingDocumentsTest3.java:50)
at com.dcm.sharingdocuments.SharingDocumentsTest3.execute(SharingDocumentsTest3.java:75)
at com.dcm.sharingdocuments.SharingDocumentsTest3.main(SharingDocumentsTest3.java:65)
So the code fails at credential.refreshToken() when I set the setServiceAccountUser. It appears to have successfully refreshed the token when I do not. I have tried various combinations of this code – e.g. commented out the refreshToken() lines, commented out the getDriveService(null) line – but whenever I try to use/refresh the credential obtained for the impersonated user I get the 401 Unauthorized error.
If I modify the code so that the drive obtained by getDriveService(null) is passed to DisplayFiles(...), then I get one file listed called “Getting Started”. So it seems that the service account authorization is working and Google have added their default file to the Drive for the server account.
I am using google-*1.22.0.jar files and Java 1.8 to the run the above code
The problem I think is in the way I have configured the domain or the way I am trying to impersonate the user but my code looks as many examples on the web do and Google Support appear to say that I have configured the domain correctly.
Anything you can suggest as a resolution or next step would be much appreciated!
I have been stuck on this problem for a long time and I finally found my problem. There is definitely a bug in the "Manage API client access" Admin console...
You must put the "Client ID" (e.g. 110xxxxxxxxx342) for the client name and NOT the "Service Account ID" (the one that looks like an email). Now, their documentation is correct, and they do say in the documentation to use the Client ID, I have to give them that.
So here is the bug. When I arrived to the Manage API screen, I saw "Example: www.example.com". I typed in the Service Account ID there, thinking that the email address format matched "www.example.com" better than the Client ID. I pressed "Authorize", and the entry had clearly been accepted and everything was good. The result looks like this:
It even generated the Client ID from the Service ID! Great! Except my code gets a 401 error every time I try to connect with setServiceUser().
If I return to the Manage API Client Access console and if I remove the previous entry and perform the same actions except use the Client ID instead of the Service ID. The result is this:
Exactly the same, but now I don't get a 401 error. So there is NO WAY to look at the console, and know if you have it successfully configured it or not. I tested this 3 times to make sure I wasn't losing my mind...
I'm in the process of making a proof of concept to dissociate the business code from the gui for the ps3 media server (http://www.ps3mediaserver.org/). For this I've got a project hosted at source forge (http://sourceforge.net/projects/pms-remote/). The client should be a simple front end to configure the server from any location within a network having the rights to connect to the server.
On the server side, all service have been exposed using javax.jws and the client proxy has been generated using wsimport.
One of the features of the current features (actually, the only blocking one), is to define the folders that will be shared by the server. As the client and server are now running as a single application on the same machine, it's trivial to browse its file system.
Problem: I'd like to expose the file system of the server machine through web services. This will allow any client (the one I'm currently working on is the same as the original using java swing) to show available folders and to select the ones that will be shown by the media server. In the end the only thing I'm interested in is an absolute folder path (string).
I thought I'd find a library giving me this functionality but couldn't find any.
Browsing the files using a UNC path and accessing a distant machine doesn't seem feasible, as it wouldn't be transparent for the user.
For now I don't want to worry about security issues, I'll figure these out once the rest seems feasible.
I'd be grateful for any input.
Thanks, Philippe
I've ended up creating a pretty simple web service letting either list all root folders or all child folders for a given path.
It's now up to the client to have a (GUI) browser to access this service.
package net.pms.plugin.webservice.filesystem;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import net.pms.plugin.webservice.ServiceBase;
#WebService(serviceName = "FileSystem", targetNamespace = "http://ps3mediaserver.org/filesystem")
public class FileSystemWebService extends ServiceBase {
#WebMethod()
public List<String> getRoots() {
List<String> roots = new ArrayList<String>();
for(File child : File.listRoots()) {
roots.add(child.getAbsolutePath());
}
return roots;
}
#WebMethod()
public List<String> getChildFolders(#WebParam(name="folderPath") String folderPath) throws FileNotFoundException {
List<String> children = new ArrayList<String>();
File d = new File(folderPath);
if(d.isDirectory()) {
for(File child : d.listFiles()) {
if(child.isDirectory() && !child.isHidden()) {
children.add(child.getAbsolutePath());
}
}
} else {
throw new FileNotFoundException();
}
return children;
}
}
For people wanting to use this, here's the ServiceBase class as well
package net.pms.plugin.webservice;
import javax.xml.ws.Endpoint;
import org.apache.log4j.Logger;
public abstract class ServiceBase {
private static final Logger log = Logger.getLogger(ServiceBase.class);
protected boolean isInitialized;
/**
* the published endpoint
*/
private Endpoint endpoint = null;
/**
*
* Start to listen for remote requests
*
* #param host ip or host name
* #param port port to use
* #param path name of the web service
*/
public void bind(String host, int port, String path) {
String endpointURL = "http://" + host + ":" + port + "/" + path;
try {
endpoint = Endpoint.publish(endpointURL, this);
isInitialized = true;
log.info("Sucessfully bound enpoint: " + endpointURL);
} catch (Exception e) {
log.error("Failed to bind enpoint: " + endpointURL, e);
}
}
/**
* Stop the webservice
*/
public void shutdown() {
log.info("Shut down " + getClass().getName());
if (endpoint != null)
endpoint.stop();
endpoint = null;
}
}
From the client, you might be able to leverage the output of smbclient -L. On the server, a suitable servlet might do.
If you set the "com.sun.management.jmxremote" system property when you start a JVM, you can run jconsole or visualvm and connect to that local mBeanServer. I want to do the same thing they are doing but can't figure out how.
Is there a service URL you can use to identify a locally running JVM?
I know I could do this by setting up a jmxmp or rmi listener on a specific port and then connecting to that port, but I don't want to do that because it means I have to manage the ports and know which port goes to which jvm (we run multiple jvms on the same server).
Thanks to Nicholas and Scott for the post and discussion. Was able to piece this together based on that info and some trial and error.
Sharing so others don't have to do the same leg work. This will attach to a JVM and get its memory usage.
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
import com.sun.tools.attach.spi.AttachProvider;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
public class AttachFun {
public static void main(String[] args) throws Exception {
final AttachProvider attachProvider = AttachProvider.providers().get(0);
VirtualMachineDescriptor descriptor = null;
for (VirtualMachineDescriptor virtualMachineDescriptor : attachProvider.listVirtualMachines()) {
if (pickThisOne(virtualMachineDescriptor)) {
descriptor = virtualMachineDescriptor;
break;
}
}
if (descriptor == null) throw new RuntimeException("You didn't pick one");
final VirtualMachine virtualMachine = attachProvider.attachVirtualMachine(descriptor);
virtualMachine.loadAgent("/System/Library/Frameworks/JavaVM.framework/Home/lib/management-agent.jar", "com.sun.management.jmxremote");
final Object portObject = virtualMachine.getAgentProperties().get("com.sun.management.jmxremote.localConnectorAddress");
final JMXServiceURL target = new JMXServiceURL(portObject + "");
final JMXConnector connector = JMXConnectorFactory.connect(target);
final MBeanServerConnection remote = connector.getMBeanServerConnection();
final ObjectName memory = new ObjectName("java.lang:type=Memory");
CompositeData cd = (CompositeData) remote.getAttribute(memory, "HeapMemoryUsage");
final Long used = (Long) cd.get("used");
System.out.println(used);
}
private static boolean pickThisOne(VirtualMachineDescriptor virtualMachineDescriptor) {
// TODO
return false;
}
}
You need the Attach API. It will locate running [Attach API capable] JVMs on the same host and return meta-data on each as well as enable a JMXConnector. It's basically what you see when you start JConsole and the connect menu displays running JVMs, including Java 1.6+ instances that were not started with any special JMX command line directives.
//Nicholas
We found this issue while implementing a reconnect logic for a WS endpoint using JAX-WS stack deployed on Glassfishv2.1 server. We deploy the web service on a cluster environment. To simplify the deployment, we use 0.0.0.0 as the IP on which the endpoint needs to be published, so that it can be accessed from all available IPs pertaining to the nodes of the cluster. Following is the code snippet for initialization of the WS(Web Service):
import javax.xml.ws.Endpoint;
.
.
//Implementor is the corresponding implementation object for the WS
Endpoint receiver = Endpoint.create(new Implementor());
.
receiver.setExecutor(threadPoolExecutor);
receiver.publish ("http://0.0.0.0:9545/context");
We call receiver.stop() to stop publishing the endpoint in our cleanup code. That's where we receive a null pointer exception with the following stack trace:
java.lang.NullPointerException
at com.sun.xml.ws.transport.http.server.ServerMgr.removeContext(ServerMgr.java:123)
at com.sun.xml.ws.transport.http.server.HttpEndpoint.stop(HttpEndpoint.java:110)
at com.sun.xml.ws.transport.http.server.EndpointImpl.stop(EndpointImpl.java:167
While trying to find the cause of the NPE, we found that the ServerMgr class depends on the InetSocketAddress of the HttpServer that listen on the ip:port of the URL where the WS endpoint is published, to retrieve some state information from a map. Since the inet address "inet:/0.0.0.0" is interpreted as "inet:/0:0:0:0:0:0:0:0" it could not find the entry in the map and hence the NPE. Here is the source code of ServerMgr.
In order to prove that this is in fact the problem, we tried to replicate the logic of the ServerMgr code related to InetSocketAddress as the following program:
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Main {
static final String URL_1 = "http://0.0.0.0:9545/context";
static final String URL_2 = "http://127.0.0.1:9548/context";
static final String URL_3 = "http://10.226.90.217:9549/context";
public void testUrl(String address){
try {
URL url = new URL(address);
Map<InetSocketAddress, Integer> map = new HashMap<InetSocketAddress, Integer>();
InetSocketAddress iaddr = new InetSocketAddress(url.getHost(), url.getPort());
map.put(iaddr, 1);
HttpServer server = HttpServer.create(iaddr, 5);
HttpContext context = server.createContext(url.toURI().getPath());
server.start();
System.out.println("original inet:"+iaddr+" and final inet:"+context.getServer().getAddress());
if(iaddr.equals(context.getServer().getAddress())){
System.out.println("equal");
Integer t = map.get(context.getServer().getAddress());
if( t == null){
System.out.println("You won");
}else{
System.out.println("You lose "+t);
}
}else{
System.out.println("not-equal");
}
server.stop(0);
map.clear();
} catch (URISyntaxException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String[] args)
{
Main d = new Main();
d.testUrl(Main.URL_1);
d.testUrl(Main.URL_2);
d.testUrl(Main.URL_3);
}
}
Odd enough we obtain the following result in my WindowsXP box ( Java version 1.6.0_22)
equal--
original inet:/0.0.0.0:9545 and final inet:/0.0.0.0:9545
equal
You lose 1
equal--
original inet:/127.0.0.1:9548 and final inet:/127.0.0.1:9548
equal
You lose 1
equal--
original inet:/10.226.92.47:9549 and final inet:/10.226.92.47:9549
equal
You lose 1
and the following output on my dev box
(Linux tahoe 2.6.9-67.EL #1 Wed Nov 7 13:43:31 EST 2007 x86_64 x86_64 x86_64 GNU/Linux)
(Java version 1.6.0_17)
run:
original inet:/0.0.0.0:9545 and final inet:/0:0:0:0:0:0:0:0:9545
not-equal
original inet:/127.0.0.1:9548 and final inet:/127.0.0.1:9548
equal
You lose 1
original inet:/10.226.90.217:9549 and final inet:/10.226.90.217:9549
equal
You lose 1
Based on the background - I have two questions:
a. Why is the 0.0.0.0 is interpreted
as IPv6 address ? (In addition, is it a problem
with the OS or the JRE ? Is it a bug
or a feature ? etc)
b. Do we have a way to configure
JRE to interpret 0.0.0.0 as IPv4 address ?
(We want to keep using 0.0.0.0 as the endpoint
address as it simplifies deployment
of our Web Service)
You can replace the 0.0.0.0 with InetAddress.getLocalHost().getHostAddress();
It will automatically resolve correctly and there is no need of -Djava.net.preferIPv4Stack=true
Have you tried by forcing the IPv4 choice as a variable to the java executable?
-Djava.net.preferIPv4Stack=true
Take a look here and here..
It's also possible to force IPv4 from your code with System.setProperty("java.net.preferIPv4Stack" , "true");