Here is the scenario:
I want to use docuwiki to show help and other content to users. The users are grouped by to organization. Each organization gets their own content that should be private to them. Enter ACL. I get how I can create a user and limit him to a certain subsection of the wiki.
Now the fun part begins. How can I authenticate these users from my server? I'm running a Tomcat/Java/MSSQL stack. I have full control of both servers.
I'd imagine if it is possible, I would imagine I can post the username/password to the wiki from the servlet, and get some kinda token back that the user can access the site with. But I don't see anything in the documentation about this. If anyone has any ideas, pointers or alternatives, I'd appreciate it.
I think the thing that you need is named Single Sign On (SSO). As a possible solution you could setup an SSO provider (there is vast variety of them, also with support of Tomcat and dokuwiki) and configure your dokuwiki and tomcat to use it. Here is a sample of such provider.
For googlers that come after me:
I ended up writing my own authenticator. TO use authenticator place it in *\inc\auth* with the name sqlsrv.class.php (sqlsrv will be the code you use to specify this authenticator.)
Basically what happens with this is I generate a token on my server that uniquely identifies a logged in user. I then POST or GET to the wiki with the token. The authenticator then queries the server to see if the user should be authenticated, as well as to get the name, email and which ACL groups the user should belong to.
Notes: make sure you change the config options in the php file. And you'll need sqlsrv installed and enabled for your apache/php.
<?php
/**
* sqlsrv authentication backend
*
* #license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* #author Yuriy Shikhanovich <yuriys#gmail.com>
*/
class auth_sqlsrv extends auth_basic {
/**
* Constructor
*
* Carry out sanity checks to ensure the object is
* able to operate. Set capabilities.
*
* #author Yuriy Shikhanovich <yuriys#gmail.com>
*/
function __construct() {
global $config_cascade;
global $connection;
$this->cando['external'] = true;
}
function trustExternal()
{
//$msgTxt = $_SESSION[DOKU_COOKIE]['auth']['info']['user']."x";
//msg($msgTxt);
//return true;
global $USERINFO;
global $conf;
global $connection;
//already logged in, no need to hit server
if (!empty($_SESSION[DOKU_COOKIE]['auth']['info']))
{
$USERINFO['name'] = $_SESSION[DOKU_COOKIE]['auth']['info']['user'];
$USERINFO['mail'] = $_SESSION[DOKU_COOKIE]['auth']['info']['mail'];
$USERINFO['grps'] = $_SESSION[DOKU_COOKIE]['auth']['info']['grps'];
$_SERVER['REMOTE_USER'] = $_SESSION[DOKU_COOKIE]['auth']['user'];
return true;
}
//check server based on token
try
{
$token = $_GET["token"];
if($token==null)
$token = $_POST["token"];
if($token==null)
$token = $_SESSION[DOKU_COOKIE]['auth']['token'];
if($token==null)
{
msg("Could not authenticate. Please contact your admin.");
return false;
}
//config //NOTE: replace with the appropriate values
$myServer = "1.1.1.1,1433";
$myUser = "sqlaccount";
$myPass = "sqlpassword";
$myDB = "dbName";
//end config
//get connection
$connectionInfo = array('UID' => $myUser, 'PWD' => $myPass, "Database"=>$myDB);
$link = sqlsrv_connect($myServer, $connectionInfo);
//check connection
if($link === FALSE)
{
msg("Could not get connection, contact your admin.");
return false;
}
//run token against proc
//NOTE: this needs to be implemented on your server, returns :
//"user" - Name of the user //this does not have to be setup in the wiki
//"email" - user's email //this does not have to be setup in the wiki
//"groups" - Which groups //this *does* have to be setup in the wiki to be used with ACL
$sql = "exec WikiLogin '".$token."'";
$stmt = sqlsrv_query( $link, $sql);
//check statement
if( $stmt === false)
{
msg("Could not get connection statement, contact your admin.");
return false;
}
//if returned results, set user and groups
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) )
{
// set the globals if authed
$USERINFO['name'] = $row['user'];
$USERINFO['mail'] = $row['email'];
$USERINFO['grps'] = split(" ",$row['groups']);
//msg(implode($row," "));
//msg(implode($USERINFO," "));
$_SERVER['REMOTE_USER'] = $row['user'];
//uncomment after testing
$_SESSION[DOKU_COOKIE]['auth']['user'] = $row['user'];
$_SESSION[DOKU_COOKIE]['auth']['mail'] = $row['email'];
$_SESSION[DOKU_COOKIE]['auth']['token'] = $token;
$_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
sqlsrv_free_stmt( $stmt);
sqlsrv_close($link);
return true;
}
return false;
if(isset($link))
sqlsrv_close($link);
else
msg("Could not get connection, contact your admin.");
if(isset($stmt))
sqlsrv_free_stmt($stmt);
else
msg("Could not get connection, contact your admin.");
}
catch (Exception $e)
{
if(isset($link))
sqlsrv_close($link);
else
msg("Could not get connection, contact your admin.");
if(isset($stmt))
sqlsrv_free_stmt($stmt);
else
msg("Could not get connection, contact your admin.");
}
}
}
Related
I am currently attempting to read/write to memory through the use of JNA for Java. For the past week I have tried a multitude of solutions, mostly from [similar projects][1] I have found online, but nothing has resolved my problem.
I know I am receiving the correct process ID of the program, then I create a Pointer using the openProcess method. Then I call getBaseAddress using the newly created Pointer. The problem I believe lies within the EnumProcessModules/Psapi method/class.
Truthfully I am slightly in over my head but this is one of the last issues I am having with this program. My overall goal is to find the base address of the program, use various offsets to access the information I am trying to modify, and then modify it appropriately. The program is 32-bit, which I have seen other people say you need to use a EnumProcessModulesEx method for? but truthfully I am unsure of how/where to implement that.
Any help would be appreciated!
You're getting an Access Denied error because Windows requires you to enable Debug privilege on your current process before accessing the memory of another process. So you will need to both run your program as Administrator, and before you call your OpenProcess code, enable debug privilege.
Here's the JNA code in my application that does this. It's a static method as I only call it once for the entire application:
/**
* Enables debug privileges for this process, required for OpenProcess() to get
* processes other than the current user
*
* #return {#code true} if debug privileges were successfully enabled.
*/
private static boolean enableDebugPrivilege() {
HANDLEByReference hToken = new HANDLEByReference();
boolean success = Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(),
WinNT.TOKEN_QUERY | WinNT.TOKEN_ADJUST_PRIVILEGES, hToken);
if (!success) {
LOG.error("OpenProcessToken failed. Error: {}", Native.getLastError());
return false;
}
try {
WinNT.LUID luid = new WinNT.LUID();
success = Advapi32.INSTANCE.LookupPrivilegeValue(null, WinNT.SE_DEBUG_NAME, luid);
if (!success) {
LOG.error("LookupPrivilegeValue failed. Error: {}", Native.getLastError());
return false;
}
WinNT.TOKEN_PRIVILEGES tkp = new WinNT.TOKEN_PRIVILEGES(1);
tkp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(luid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED));
success = Advapi32.INSTANCE.AdjustTokenPrivileges(hToken.getValue(), false, tkp, 0, null, null);
int err = Native.getLastError();
if (!success) {
LOG.error("AdjustTokenPrivileges failed. Error: {}", err);
return false;
} else if (err == WinError.ERROR_NOT_ALL_ASSIGNED) {
LOG.debug("Debug privileges not enabled.");
return false;
}
} finally {
Kernel32.INSTANCE.CloseHandle(hToken.getValue());
}
return true;
}
I'm not sure from looking at your code whether you also have the right permissions for OpenProcess. Be sure you have the VM_READ permission. Here's what I use, your mileage may vary (I assume you'll need writing permissions as well).
final HANDLE pHandle = Kernel32.INSTANCE.OpenProcess(
WinNT.PROCESS_QUERY_INFORMATION | WinNT.PROCESS_VM_READ,
false, processID);
I have used below mentioned API of dcm4che2 from this repository http://www.dcm4che.org/maven2/dcm4che/ in my java project.
dcm4che-core-2.0.29.jar
org.dcm4che2.data.DicomObject
org.dcm4che2.io.StopTagInputHandler
org.dcm4che2.data.BasicDicomObject
org.dcm4che2.data.UIDDictionary
org.dcm4che2.data.DicomElement
org.dcm4che2.data.SimpleDcmElement
org.dcm4che2.net.service.StorageCommitmentService
org.dcm4che2.util.CloseUtils
dcm4che-net-2.0.29.jar
org.dcm4che2.net.CommandUtils
org.dcm4che2.net.ConfigurationException
org.dcm4che2.net.NetworkApplicationEntity
org.dcm4che2.net.NetworkConnection
org.dcm4che2.net.NewThreadExecutor
org.dcm4che3.net.service.StorageService
org.dcm4che3.net.service.VerificationService
Currently i want to migrate to dcm4che3 but, above listed API is not found in dcm4che3 which i have downloaded from this repository http://sourceforge.net/projects/dcm4che/files/dcm4che3/
Could you please guide me for alternate approach?
As you have already observed, the BasicDicomObject is history -- alongside quite a few others.
The new "Dicom object" is Attributes -- an object is a collection of attributes.
Therefore, you create Attributes, populate them with the tags you need for RQ-behaviour (C-FIND, etc) and what you get in return is another Attributes object from which you pull the tags you want.
In my opinion, dcm4che 2.x was vague on the subject of dealing with individual value representations. dcm4che 3.x is quite a bit clearer.
The migration demands a rewrite of your code regarding how you query and how you treat individual tags. On the other hand, dcm4che 3.x makes the new code less convoluted.
On request, I have added the initial setup of a connection to some service class provider (SCP):
// Based on org.dcm4che:dcm4che-core:5.25.0 and org.dcm4che:dcm4che-net:5.25.0
import org.dcm4che3.data.*;
import org.dcm4che3.net.*;
import org.dcm4che3.net.pdu.AAssociateRQ;
import org.dcm4che3.net.pdu.PresentationContext;
import org.dcm4che3.net.pdu.RoleSelection;
import org.dcm4che3.net.pdu.UserIdentityRQ;
// Client side representation of the connection. As a client, I will
// not be listening for incoming traffic (but I could choose to do so
// if I need to transfer data via MOVE)
Connection local = new Connection();
local.setHostname("client.on.network.com");
local.setPort(Connection.NOT_LISTENING);
// Remote side representation of the connection
Connection remote = new Connection();
remote.setHostname("pacs.on.network.com");
remote.setPort(4100);
remote.setTlsProtocols(local.getTlsProtocols());
remote.setTlsCipherSuites(local.getTlsCipherSuites());
// Calling application entity
ApplicationEntity ae = new ApplicationEntity("MeAsAServiceClassUser".toUpperCase());
ae.setAETitle("MeAsAServiceClassUser");
ae.addConnection(local); // on which we may not be listening
ae.setAssociationInitiator(true);
ae.setAssociationAcceptor(false);
// Device
Device device = new Device("MeAsAServiceClassUser".toLowerCase());
device.addConnection(local);
device.addApplicationEntity(ae);
// Configure association
AAssociateRQ rq = new AAssociateRQ();
rq.setCallingAET("MeAsAServiceClassUser");
rq.setCalledAET("NameThatIdentifiesTheProvider"); // e.g. "GEPACS"
rq.setImplVersionName("MY-SCU-1.0"); // Max 16 chars
// Credentials (if appropriate)
String username = "username";
String passcode = "so secret";
if (null != username && username.length() > 0 && null != passcode && passcode.length() > 0) {
rq.setUserIdentityRQ(UserIdentityRQ.usernamePasscode(username, passcode.toCharArray(), true));
}
Example, pinging the PACS (using the setup above):
String[] TRANSFER_SYNTAX_CHAIN = {
UID.ExplicitVRLittleEndian,
UID.ImplicitVRLittleEndian
};
// Define transfer capabilities for verification SOP class
ae.addTransferCapability(
new TransferCapability(null,
/* SOP Class */ UID.Verification,
/* Role */ TransferCapability.Role.SCU,
/* Transfer syntax */ TRANSFER_SYNTAX_CHAIN)
);
// Setup presentation context
rq.addPresentationContext(
new PresentationContext(
rq.getNumberOfPresentationContexts() * 2 + 1,
/* abstract syntax */ UID.Verification,
/* transfer syntax */ TRANSFER_SYNTAX_CHAIN
)
);
rq.addRoleSelection(new RoleSelection(UID.Verification, /* is SCU? */ true, /* is SCP? */ false));
try {
// 1) Open a connection to the SCP
Association association = ae.connect(local, remote, rq);
// 2) PING!
DimseRSP rsp = association.cecho();
rsp.next(); // Consume reply, which may fail
// Still here? Success!
// 3) Close the connection to the SCP
if (as.isReadyForDataTransfer()) {
as.waitForOutstandingRSP();
as.release();
}
} catch (Throwable ignore) {
// Failure
}
Another example, retrieving studies from a PACS given accession numbers; setting up the query and handling the result:
String modality = null; // e.g. "OT"
String accessionNumber = "1234567890";
//--------------------------------------------------------
// HERE follows setup of a query, using an Attributes object
//--------------------------------------------------------
Attributes query = new Attributes();
// Indicate character set
{
int tag = Tag.SpecificCharacterSet;
VR vr = ElementDictionary.vrOf(tag, query.getPrivateCreator(tag));
query.setString(tag, vr, "ISO_IR 100");
}
// Study level query
{
int tag = Tag.QueryRetrieveLevel;
VR vr = ElementDictionary.vrOf(tag, query.getPrivateCreator(tag));
query.setString(tag, vr, "STUDY");
}
// Accession number
{
int tag = Tag.AccessionNumber;
VR vr = ElementDictionary.vrOf(tag, query.getPrivateCreator(tag));
query.setString(tag, vr, accessionNumber);
}
// Optionally filter on modality in study if 'modality' is provided,
// otherwise retrieve modality
{
int tag = Tag.ModalitiesInStudy;
VR vr = ElementDictionary.vrOf(tag, query.getPrivateCreator(tag));
if (null != modality && modality.length() > 0) {
query.setString(tag, vr, modality);
} else {
query.setNull(tag, vr);
}
}
// We are interested in study instance UID
{
int tag = Tag.StudyInstanceUID;
VR vr = ElementDictionary.vrOf(tag, query.getPrivateCreator(tag));
query.setNull(tag, vr);
}
// Do the actual query, needing an AppliationEntity (ae),
// a local (local) and remote (remote) Connection, and
// an AAssociateRQ (rq) set up earlier.
try {
// 1) Open a connection to the SCP
Association as = ae.connect(local, remote, rq);
// 2) Query
int priority = 0x0002; // low for the sake of demo :)
as.cfind(UID.StudyRootQueryRetrieveInformationModelFind, priority, query, null,
new DimseRSPHandler(as.nextMessageID()) {
#Override
public void onDimseRSP(Association assoc, Attributes cmd,
Attributes response) {
super.onDimseRSP(assoc, cmd, response);
int status = cmd.getInt(Tag.Status, -1);
if (Status.isPending(status)) {
//--------------------------------------------------------
// HERE follows handling of the response, which
// is just another Attributes object
//--------------------------------------------------------
String studyInstanceUID = response.getString(Tag.StudyInstanceUID);
// etc...
}
}
});
// 3) Close the connection to the SCP
if (as.isReadyForDataTransfer()) {
as.waitForOutstandingRSP();
as.release();
}
}
catch (Exception e) {
// Failure
}
More on this at https://github.com/FrodeRanders/dicom-tools
I am trying to get the details of the user that invoked the JMX operation for logging purpose. I have tried below code. But that does not seem to work as it returns blank each time. What am I dooing wrong. Or is there any better way of doing this?
private String getUserName() {
AccessControlContext acc = AccessController.getContext();
Subject subject = Subject.getSubject(acc);
if (subject != null) {
Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
JMXPrincipal principal = principals.iterator().next();
return principal.getName();
}
return "";
}
The above code did work.
What I did (for all that might be wondering like I was):
1) Added following JVM args
-Dcom.sun.management.jmxremote.ssl=**false**
-Dcom.sun.management.jmxremote.authenticate=**true**
-Dcom.sun.management.jmxremote.access.file=**PATH-TO jmxremote.access**
-Dcom.sun.management.jmxremote.password.file=**PATH-TO jmxremote.password**
2) Added following entries in the jmxremote.access file
admin readwrite \ create javax.management.monitor.*,javax.management.timer.* \ unregister
user readonly
3) Added below lines in the jmxremote.password file
admin adminPassword
user userPassword
4) Added the below code in my MBean java file and called the method getUserName() inside the JMXoperation
private String getUserName() {
AccessControlContext acc = AccessController.getContext();
Subject subject = Subject.getSubject(acc);
if (subject != null) {
Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
JMXPrincipal principal = principals.iterator().next();
return principal.getName();
}
return "";
}
When I run it in debug mode, I am seeing the user that invoked the JMXOperation.
I am working on an android app used to access a Box account. The problem I am facing is how to determine a folder/file in the user's account is read only (shared with him/her as a Viewer) so that the upload/delete operations can be disabled.
What I currently do is:
1) Get the items in a folder:
BoxCollection itemsCollection = _boxClient.getFoldersManager()
.getFolderItems(folderId, folderContentRequest);
String userMail = ...
ArrayList<BoxTypedObject> result = null;
2) Determine which one is folder, get it's collaborations, check if it's accessible by the logged-in user, and check whether he is an editor:
if (itemsCollection != null) {
result = itemsCollection.getEntries();
for(BoxTypedObject boxObject : result) {
if(boxObject instanceof BoxAndroidFolder) {
BoxAndroidFolder folder = (BoxAndroidFolder)boxObject;
List<BoxCollaboration> folderCollaborations = _boxClient.getFoldersManager().getFolderCollaborations(folder.getId(), null);
for(BoxCollaboration collaboration : folderCollaborations) {
if( userMail.equalsIgnoreCase(collaboration.getAccessibleBy().getLogin()) &&
!BoxCollaborationRole.EDITOR.equalsIgnoreCase(collaboration.getRole()))
System.out.println("" + folder.getName() + " is readonly");
}
}
}
}
So, is there a simpler and faster (fewer requests) way to get that property of a folder with the android SDK?
You can first check the owner of the folder (folder.getOwnedBy()), if it's the current user then you don't need to check collaborations. However if it's not the current user you'll have to check collaborations.
I have this classes for my app:
NewsApp.java
ScreenApp.java
Item.java
ui/TableList.java
The app retrieve a list of links from a webservice (.net), I use KSoap Library (as Reference project).
I use JDE 4.5 for develop, because with Eclipse I cant use the method "setRowHeight(index, int)" of ListField class, then I need use JDE 4.5
Ok, I compile the app (F7 key), and run in simulator (F5 key).
In simulator, go to the icon app, and try to open... nothing happends... the app not open... are strange... no error message (ScreenApp.java line 57)... but... if I few more minutes... I see the error message (ScreenApp.java line 57)... I think maybe is because the app try connect...
Later... I think is because not exists a internet connection in simulator (I see EDGE in the top of simulator... is strange), I stop de simulator, open MDS, and run simulator again (F5 key), and now works... the list show correctly... and I can open the links in the blackberry browser.
Now... I put all compiled files in same directory, create a ALX file:
NewsApp.alx
And install this app on device, the installation works ok, I go to the list of applications on device (8520), Open the app and I see the connection message (ScreenApp.java line 57);
I dont understand why ? in this phone (8520) I have EDGE connection with my carrier, I have the WIFI active... I can browse in any page (default browser)... but my app cant retrieve information from webservice... :(
Anybody help me please ?
You need to use Different connection parameter at the end of the url when application run on the device.
For ex. in case of wifi, you need to append ;interface=wifi" at the end of the URL.
Detail code is: you need to call getConnectionString() to get the connection sufix according to device network. I hope this will solve your problem.
/**
* #return connection string
*/
static String getConnectionString()
{
// This code is based on the connection code developed by Mike Nelson of AccelGolf.
// http://blog.accelgolf.com/2009/05/22/blackberry-cross-carrier-and-cross-network-http-connection
String connectionString = null;
// Simulator behavior is controlled by the USE_MDS_IN_SIMULATOR variable.
if(DeviceInfo.isSimulator())
{
// logMessage("Device is a simulator and USE_MDS_IN_SIMULATOR is true");
connectionString = ";deviceside=true";
}
// Wifi is the preferred transmission method
else if(WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED)
{
// logMessage("Device is connected via Wifi.");
connectionString = ";interface=wifi";
}
// Is the carrier network the only way to connect?
else if((CoverageInfo.getCoverageStatus() & CoverageInfo.COVERAGE_DIRECT) == CoverageInfo.COVERAGE_DIRECT)
{
//logMessage("Carrier coverage.");
String carrierUid = getCarrierBIBSUid();
if(carrierUid == null)
{
// Has carrier coverage, but not BIBS. So use the carrier's TCP network
// logMessage("No Uid");
connectionString = ";deviceside=true";
}
else
{
// otherwise, use the Uid to construct a valid carrier BIBS request
// logMessage("uid is: " + carrierUid);
connectionString = ";deviceside=false;connectionUID="+carrierUid + ";ConnectionType=mds-public";
}
}
// Check for an MDS connection instead (BlackBerry Enterprise Server)
else if((CoverageInfo.getCoverageStatus() & CoverageInfo.COVERAGE_MDS) == CoverageInfo.COVERAGE_MDS)
{
// logMessage("MDS coverage found");
connectionString = ";deviceside=false";
}
// If there is no connection available abort to avoid bugging the user unnecssarily.
else if(CoverageInfo.getCoverageStatus() == CoverageInfo.COVERAGE_NONE)
{
//logMessage("There is no available connection.");
}
// In theory, all bases are covered so this shouldn't be reachable.
else
{
//logMessage("no other options found, assuming device.");
connectionString = ";deviceside=true";
}
return connectionString;
}
/**
* Looks through the phone's service book for a carrier provided BIBS network
* #return The uid used to connect to that network.
*/
private static String getCarrierBIBSUid()
{
ServiceRecord[] records = ServiceBook.getSB().getRecords();
int currentRecord;
for(currentRecord = 0; currentRecord < records.length; currentRecord++)
{
if(records[currentRecord].getCid().toLowerCase().equals("ippp"))
{
if(records[currentRecord].getName().toLowerCase().indexOf("bibs") >= 0)
{
return records[currentRecord].getUid();
}
}
}
return null;
}