OpenSAML3.3 Correct way to read (adfs) FederationService.xml? - java

I'm integrating OpenSAML 3.3 in my application, and instead of hard-coding all the urls etc, I would like to be able to use the configuration XMLs.
I was given such an XML file for a adfs instance, it is 'FederationMetadata.xml'
This is the snippet I used to read it:
InitializationService.initialize();
FilesystemMetadataResolver idpMetaDataProvider = new FilesystemMetadataResolver( new File("/home/raudenaerde/sso/FederationMetadata.xml") );
idpMetaDataProvider.setRequireValidMetadata(true);
idpMetaDataProvider.setParserPool(new BasicParserPool());
idpMetaDataProvider.initialize();
However, this gave me this error:
> Exception in thread "main"
> net.shibboleth.utilities.java.support.component.ComponentInitializationException:
> Component identifier can not be null
Using an github project (https://github.com/coveo/saml-client) that uses OpenSAML 2.6.4 I had no problems reading it, but I'd like to stick with the newest version 3.3.
Am I missing some basic set-up?

There are 2 things that needed to be fixed:
In OpenSaml v3 many class instances are required to have an ID, setId(String) must be called before initialize()
The BasicParserPool needs to be initialized as well.
Complete working code:
InitializationService.initialize();
FilesystemMetadataResolver idpMetaDataProvider = new FilesystemMetadataResolver( new File( "/home/raudenaerde/sso/FederationMetadata.xml" ) );
idpMetaDataProvider.setRequireValidMetadata( true );
idpMetaDataProvider.setId( "myId" );
BasicParserPool pool = new BasicParserPool();
pool.initialize();
idpMetaDataProvider.setParserPool( pool );
idpMetaDataProvider.initialize();
for ( EntityDescriptor idpEntityDescriptor : idpMetaDataProvider )
{
System.out.println( idpEntityDescriptor.getID() );
for ( SingleSignOnService sss : idpEntityDescriptor.getIDPSSODescriptor( SAMLConstants.SAML20P_NS ).getSingleSignOnServices() )
{
if ( sss.getBinding().equals( SAMLConstants.SAML2_REDIRECT_BINDING_URI ) )
{
System.out.println( sss.getLocation() );
}
}
for ( ArtifactResolutionService ars : idpEntityDescriptor.getIDPSSODescriptor( SAMLConstants.SAML20P_NS ).getArtifactResolutionServices() )
{
if ( ars.getBinding().equals( SAMLConstants.SAML2_SOAP11_BINDING_URI ) )
{
System.out.println( ars.getLocation() );
}
}
}

Related

Dynamic datasource connection in Quarkus

My question is similar to the one in this 2 year old post:
Is there a way to handle dynamic connexion to datasource with quarkus?
I have say 10 different DBs, all of them are in Postgres and they even have the same user and password, so the only thing that changes is the database name.
I have an endpoint similar to /{databasename}/customers, so I'd like to be able to retrieve the list of customers from the database name that is passed as a parameter.
I know I might try to write an extension to do that, but I have not been able to do so, and I'm not sure that I really want to modify the framework to do this.
I'd like to understand what the options are to do something like this
I thought that something similar to the code snippet below might help to dynamically connect to a DS, but there's not way for me to make it work because this is a way to programmatically set up the connection once the application is starting up:
AgroalDataSourceConfigurationSupplier configuration = new AgroalDataSourceConfigurationSupplier()
.dataSourceImplementation( AgroalDataSourceConfiguration.DataSourceImplementation.AGROAL )
.metricsEnabled( false )
.connectionPoolConfiguration( cp -> cp
.minSize( 5 )
.maxSize( 20 )
.initialSize( 10 )
.connectionValidator( AgroalConnectionPoolConfiguration.ConnectionValidator.defaultValidator() )
.acquisitionTimeout( Duration.ofSeconds( 5 ) )
.leakTimeout( Duration.ofSeconds( 5 ) )
.validationTimeout( Duration.ofSeconds( 50 ) )
.reapTimeout( Duration.ofSeconds( 500 ) )
.connectionFactoryConfiguration( cf -> cf
.jdbcUrl( "jdbc:postgresql://localhost/quarkus_test3" )
// .connectionProviderClassName( "org.h2.Driver" )
.autoCommit( false )
.jdbcTransactionIsolation( AgroalConnectionFactoryConfiguration.TransactionIsolation.SERIALIZABLE )
.principal( new NamePrincipal( "postgres" ) )
.credential( new SimplePassword( "postgres123" ) )
)
);
try ( AgroalDataSource dataSource = AgroalDataSource.from( configuration ) ) {
Connection connection = dataSource.getConnection();
connection.close();
} catch ( SQLException e ) {
System.out.println( "Oops! " + e.getMessage() );
}

How to fix PlatformExceptionImpl with code of 100 when excecuting `javax.telephony.Call#connect`?

When I calling:
final JtapiPeer jtapiPeer = JtapiPeerFactory.getJtapiPeer(null);
final CiscoProvider ciscoProvider = jtapiPeer.getProvider(String.format(CUCM_LOGIN_STRING,
telephonyPropertyCucm.getHost(),
telephonyPropertyCucm.getLogin(),
telephonyPropertyCucm.getPassword()));
final Call call = ciscoProvider.createCall();
final Address addressFrom = ciscoProvider.getAddress(from);
addressFrom.addCallObserver((callEvs) -> {});
call.connect(addressFrom.getTerminals()[0], addressFrom, to);
Then I've got sometimes a PlatformExceptionImpl:
...
Caused by: com.cisco.jtapi.PlatformExceptionImpl: Could not meet post conditions of connect()
at com.cisco.jtapi.CallImpl.connect(CTQF) ~[cisco-jtapi-0.0.1-SNAPSHOT.jar!/:11.5(1.13045)-1 Release]
at com.cisco.jtapi.CallImpl.connect(CTQF) ~[cisco-jtapi-0.0.1-SNAPSHOT.jar!/:11.5(1.13045)-1 Release]
at ru.bcs.telephony.jtapi.starter.helper.call.CallingExecutable.execute(CallingExecutable.java:33) ~[telephony-jtapi-spring-boot-starter-1.1-RELEASE.jar!/:na]
... 124 common frames omitted
I've already tried to increase JtapiPostConditionTimeout in jtapi.ini to 20 seconds (as I can see in the documentation it is the max value).
I expect that this exception doesn't appear.
But only sometimes this exception appears.
P.S. Fields of the exception are follows:
PLATFORM EXCEPTION. It's a message: Could not meet post conditions of connect(). It's error code: 100. It's error name: . It's error description:
Objects like Provider, Address, Terminal have an in-service/out-of-service state - opening one (e.g. by adding an observer) kicks off the process of connecting to CUCM CTI Manager and establishing observation/control of the object, but that takes some time.
In general, you will want to wait for in-service events for those objects to arrive before attempting any operations on them:
Handler handler = new Handler();
// Create the JtapiPeer object, representing the JTAPI library
System.out.println("Initializing Jtapi");
JtapiPeer peer = JtapiPeerFactory.getJtapiPeer( null );
// Create and open the Provider, representing a JTAPI connection to CUCM CTI Manager
String providerString = String.format( "%s;login=%s;passwd=%s",
System.getenv( "CUCM" ), System.getenv( "USER_NAME" ), System.getenv( "PASSWORD" ) );
System.out.println( "Connecting Provider: " + providerString );
Provider provider = peer.getProvider( providerString );
provider.addObserver( handler );
// Wait for ProvInServiceEv
System.out.println( "Awaiting ProvInServiceEv..." );
handler.providerInService.waitTrue();
// Retrieve and open the Address (line) object for the 'from' DN specified in the environment
CiscoAddress fromAddress = (CiscoAddress) provider.getAddress( System.getenv( "CALL_FROM" ) );
...
where Hander.java is something like:
package com.cisco.jtapi.makecall;
import javax.telephony.*;
import javax.telephony.events.*;
import javax.telephony.callcontrol.*;
import com.cisco.jtapi.extensions.*;
import com.cisco.cti.util.Condition;
public class Handler implements
ProviderObserver,
TerminalObserver,
AddressObserver,
CallControlCallObserver {
public Condition providerInService = new Condition();
public Condition terminalInService = new Condition();
public Condition addressInService = new Condition();
public Condition callActive = new Condition();
public void providerChangedEvent( ProvEv[] events ) {
if ( events != null ) {
for ( int i = 0; i < events.length; i++ ) {
System.out.println( "-->Received " + events[ i ] + " for: " + events[ i ].getProvider().getName() );
switch ( events[ i ].getID() ) {
case ProvInServiceEv.ID:
providerInService.set();
break;
}
}
}
}
...
See here for a complete sample: https://github.com/CiscoDevNet/jtapi-samples

How to register for WMI events using Java

I am integrating window based application with java application and want to capture window events in java.
I found in google J-Interop is the library thorugh this can be achived.
i did some POC wih below code but facing issue while locating the service i.e WbemScripting.SWbemLocator
import java.io.IOException;
import java.util.logging.Level;
import org.jinterop.dcom.common.JIException;
import org.jinterop.dcom.common.JISystem;
import org.jinterop.dcom.core.JIComServer;
import org.jinterop.dcom.core.JIProgId;
import org.jinterop.dcom.core.JISession;
import org.jinterop.dcom.core.JIString;
import org.jinterop.dcom.core.JIVariant;
import org.jinterop.dcom.impls.JIObjectFactory;
import org.jinterop.dcom.impls.automation.IJIDispatch;
public class EventLogListener
{
private static final String WMI_DEFAULT_NAMESPACE = "ROOT\\CIMV2";
private static String domainName = "domain";
private static String userName="user";
private static String password="psswd";
private static String hostIP ="127.0.0.1";
private static JISession configAndConnectDCom( String domain, String user, String pass ) throws Exception
{
JISystem.getLogger().setLevel( Level.OFF );
try
{
JISystem.setInBuiltLogHandler( false );
}
catch ( IOException ignored )
{
;
}
// JISystem.setAutoRegisteration( true );
JISession dcomSession = JISession.createSession( domain, user, pass );
dcomSession.useSessionSecurity( true );
return dcomSession;
}
private static IJIDispatch getWmiLocator( String host, JISession dcomSession ) throws Exception
{
//HKEY_CLASSES_ROOT\CLSID\{76A64158-CB41-11D1-8B02-00600806D9B6}
//WbemScripting.SWbemLocator
JIComServer wbemLocatorComObj = new JIComServer( JIProgId.valueOf( "76A64158-CB41-11D1-8B02-00600806D9B6" ), host, dcomSession );
System.out.println("com objected created");
return (IJIDispatch) JIObjectFactory.narrowObject( wbemLocatorComObj.createInstance().queryInterface( IJIDispatch.IID ) );
}
private static IJIDispatch toIDispatch( JIVariant comObjectAsVariant ) throws JIException
{
return (IJIDispatch) JIObjectFactory.narrowObject( comObjectAsVariant.getObjectAsComObject() );
}
public static void main( String[] args )
{
String domain = domainName;//args[ 0 ];
String host = hostIP;//args[ 1 ];
String user = userName;//args[ 2 ];
String pass = password;//args[ 3 ];
JISession dcomSession = null;
try
{
// Connect to DCOM on the remote system, and create an instance of the WbemScripting.SWbemLocator object to talk to WMI.
dcomSession = configAndConnectDCom( domain, user, pass );
IJIDispatch wbemLocator = getWmiLocator( host, dcomSession );
// Invoke the "ConnectServer" method on the SWbemLocator object via it's IDispatch COM pointer. We will connect to
// the default ROOT\CIMV2 namespace. This will result in us having a reference to a "SWbemServices" object.
JIVariant results[] =
wbemLocator.callMethodA( "ConnectServer", new Object[] { new JIString( host ), new JIString( WMI_DEFAULT_NAMESPACE ),
JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), new Integer( 0 ),
JIVariant.OPTIONAL_PARAM() } );
IJIDispatch wbemServices = toIDispatch( results[ 0 ] );
// Now that we have a SWbemServices DCOM object reference, we prepare a WMI Query Language (WQL) request to be informed whenever a
// new instance of the "Win32_NTLogEvent" WMI class is created on the remote host. This is submitted to the remote host via the
// "ExecNotificationQuery" method on SWbemServices. This gives us all events as they come in. Refer to WQL documentation to
// learn how to restrict the query if you want a narrower focus.
final String QUERY_FOR_ALL_LOG_EVENTS = "SELECT * FROM __InstanceCreationEvent WHERE TargetInstance ISA 'Win32_NTLogEvent'";
final int RETURN_IMMEDIATE = 16;
final int FORWARD_ONLY = 32;
JIVariant[] eventSourceSet =
wbemServices.callMethodA( "ExecNotificationQuery", new Object[] { new JIString( QUERY_FOR_ALL_LOG_EVENTS ), new JIString( "WQL" ),
new JIVariant( new Integer( RETURN_IMMEDIATE + FORWARD_ONLY ) ) } );
IJIDispatch wbemEventSource = (IJIDispatch) JIObjectFactory.narrowObject( ( eventSourceSet[ 0 ] ).getObjectAsComObject() );
// The result of the query is a SWbemEventSource object. This object exposes a method that we can call in a loop to retrieve the
// next Windows Event Log entry whenever it is created. This "NextEvent" operation will block until we are given an event.
// Note that you can specify timeouts, see the Microsoft documentation for more details.
System.out.println("listner statred");
while ( true )
{
System.out.println("vinod");
// this blocks until an event log entry appears.
JIVariant eventAsVariant = (JIVariant) ( wbemEventSource.callMethodA( "NextEvent", new Object[] { JIVariant.OPTIONAL_PARAM() } ) )[ 0 ];
IJIDispatch wbemEvent = toIDispatch( eventAsVariant );
// WMI gives us events as SWbemObject instances (a base class of any WMI object). We know in our case we asked for a specific object
// type, so we will go ahead and invoke methods supported by that Win32_NTLogEvent class via the wbemEvent IDispatch pointer.
// In this case, we simply call the "GetObjectText_" method that returns us the entire object as a CIM formatted string. We could,
// however, ask the object for its property values via wbemEvent.get("PropertyName"). See the j-interop documentation and examples
// for how to query COM properties.
JIVariant objTextAsVariant = (JIVariant) ( wbemEvent.callMethodA( "GetObjectText_", new Object[] { new Integer( 1 ) } ) )[ 0 ];
String asText = objTextAsVariant.getObjectAsString().getString();
System.out.println( asText );
}
}
catch ( Exception e )
{
e.printStackTrace();
}
finally
{
if ( null != dcomSession )
{
try
{
JISession.destroySession( dcomSession );
}
catch ( Exception ex )
{
ex.printStackTrace();
}
}
}
}
}
Error:
org.jinterop.dcom.common.JIException: The system cannot find the file specified. Please check the path provided as parameter. If this exception is being thrown from the WinReg package, please check if the library is registered properly or do so using regsvr32. [0x00000002]
at org.jinterop.winreg.smb.JIWinRegStub.winreg_OpenKey(JIWinRegStub.java:195)
at org.jinterop.dcom.core.JIProgId.getIdFromWinReg(JIProgId.java:129)
at org.jinterop.dcom.core.JIProgId.getCorrespondingCLSID(JIProgId.java:160)
at org.jinterop.dcom.core.JIComServer.<init>(JIComServer.java:428)
at com.stg.commons.behave.reporting.EventLogListener.getWmiLocator(EventLogListener.java:49)
at com.stg.commons.behave.reporting.EventLogListener.main(EventLogListener.java:81)
Caused by: org.jinterop.dcom.common.JIRuntimeException: The system cannot find the file specified. Please check the path provided as parameter. If this exception is being thrown from the WinReg package, please check if the library is registered properly or do so using regsvr32. [0x00000002]
at org.jinterop.winreg.IJIWinReg$openKey.read(IJIWinReg.java:938)
at ndr.NdrObject.decode(NdrObject.java:36)
at rpc.ConnectionOrientedEndpoint.call(ConnectionOrientedEndpoint.java:137)
at rpc.Stub.call(Stub.java:113)
at org.jinterop.winreg.smb.JIWinRegStub.winreg_OpenKey(JIWinRegStub.java:189)
... 5 more
This is the clue:
"If this exception is being thrown from the WinReg package, please
check if the library is registered properly or do so using regsvr32."
It seems the necessary library of your Windows application is not properly registered yet. From the command prompt (in admin mode), you can use regsvr32 to do that:
regsvr32 yourlib.dll
References:
There is a similar thread here
How to register a DLL using regsvr32 can be found here

getResourceAsStream returning null despite called file being in same dir as class getResourceAsStream is called in

I imported an Android sample coded by Amazon involving AWS's DynamoDB which I got from here and was presumably written for Eclipse:
https://github.com/awslabs/aws-sdk-android-samples/tree/master/DynamoDBMapper_UserPreference
Since Android Studio (0.8.1) uses gradle instead of ant, naturally things got auto-moved around in terms of dir structure when importing so (part of) it looks like this:
PropertyLoader gets the TVM credential info it needs to connect to the database DynamoDB from AwsCredentials.properties. Relevant methods:
public class PropertyLoader {
private boolean hasCredentials = false;
private String tokenVendingMachineURL = null;
private boolean useSSL = false;
private String testTableName = null;
private static PropertyLoader instance = null;
public static PropertyLoader getInstance() {
if ( instance == null ) {
instance = new PropertyLoader();
}
return instance;
}
public PropertyLoader() {
try {
Properties properties = new Properties();
properties.load( this.getClass().getResourceAsStream( "AwsCredentials.properties" ) );
this.tokenVendingMachineURL = properties.getProperty( "tokenVendingMachineURL" );
this.useSSL = Boolean.parseBoolean( properties.getProperty( "useSSL" ) );
this.testTableName = properties.getProperty( "testTableName" );
if ( this.tokenVendingMachineURL == null || this.tokenVendingMachineURL.equals( "" ) || this.tokenVendingMachineURL.equals( "CHANGEME" ) || this.testTableName.equals( "" ) ) {
this.tokenVendingMachineURL = null;
this.useSSL = false;
this.hasCredentials = false;
this.testTableName = null;
}
else {
this.hasCredentials = true;
}
}
catch ( Exception exception ) {
Log.e( "PropertyLoader", "Unable to read property file." );
}
}
However the getResourceAsStream line properties.load( this.getClass().getResourceAsStream( "AwsCredentials.properties" ) ); returns null. As you can see in my screenshot, AwsCredentials.properties is in the same dir as PropertyLoader and matches the case, which is all that should be required based on my readings of the method:
http://mindprod.com/jgloss/getresourceasstream.html
getResourceAsStream() is always returning null
I have tried other things such as prefixing "\" (i.e. properties.load( this.getClass().getResourceAsStream( "\AwsCredentials.properties" ) ); and copying the credentials file and placing in the src folder (you can't see it in this screenshot because the explorer sorts by filetype(?) and places 'main' first, but it's there) as per this:
getResourceAsStream returning null
However, that hasn't fixed the issue either. Having tried these options and done research, I'm confused as to why it's returning null. How can I fix this?
Created a dir called resources under /src/main/ and placed AwsCredentials.properties there and used
properties.load( PropertyLoader.class.getClassLoader().getResourceAsStream( "AwsCredentials.properties" ) );
instead of
properties.load( this.getClass().getResourceAsStream("AwsCredentials.properties" ) );
Not as elegant as I would like, but it works.
For up to a day I was struggling with this as well. And finally I was able to resolve this very neatly. The problem is not in the JAVA but in the all project structure. E.g. in Android Studio the whole project is under src/main/java whereas main is a flavour of the project. So if you've file(-s) to read from in source's package (e.g.) com/my/example/app you have to edit the build.gradle file for read (clazz.getResourceAsStream(file)) to work properly. I.e. under android define sourceSets like this:
android {
/* ... Your stuff ... */
sourceSets {
// Lets have two flavours to make it more clear
main {
resources.srcDirs = ['src/main/java']
}
flavourFoo {
resources.srcDirs = ['src/flavourFoo/java']
}
}
}
Hope this helps!

Best Practice to Build a Java SDK for a REST API

I'm about to develop a Java SDK against a REST API and would like to know what would be the best practice approach to building it. I've looked at Google and also used a number of SDKs which connect to REST APIs and there is never much consistency. I've come across some patterns which I find interesting and would like to know which one could be considered best practice, if any, or if there are alternatives?
I've provided sample / pseudo code to facilitate.
1) The models / requests / client are all separated. Example call:
Client client = new Client( ... credentials ... );
try {
Something obj = client.post( new PostSomethingRequest( ..params... ) );
} catch( Exception oops ) { ...handle... }
try {
Something obj2 = client.get( new GetSomethingRequest( id ) );
} catch( Exception oops ) { ...handle... }
2) The models and request are tied together and the client is separate. Example call:
Client client = new Client( ... credentials ... );
try {
Something obj = client.post( new Something( ..params... ) );
} catch( Exception oops ) { ...handle... }
try {
Something obj2 = client.get( new Something( id ) );
} catch( Exception oops ) { ...handle... }
3) The model contains everything. Example call:
Client.setCredentials( ... credentials ... );
Something obj = new Something( ..params... );
try {
obj.post();
} catch( Exception oops ) { ...handle... }
try {
Something obj2 = Something.get( id );
} catch( Exception oops ) { ...handle... }
If there are better ways of building this I'd also be glad to hear about them.
IF you build an SDK for a special REST API, I would use method names that represent the REST service calls and won't be so generic.

Categories