Tuesday, December 20, 2016

Vagrant notes

Vagrant enables users to create and configure lightweight, reproducible, and portable development environments.

$ vagrant up

This command creates and configures guest machines according to your Vagrantfile.
Start virtual machine.

$ vagrant ssh

This will SSH into a running Vagrant machine and give you access to a shell.

$ vagrant halt

This command shuts down the running machine Vagrant is managing.

$ vagrant destroy

This command stops the running machine Vagrant is managing and destroys all resources that were created during the machine creation process.
After running this command, your computer should be left at a clean state, as if you never created the guest machine in the first place.

$ vagrant global-status

This command will tell you the state of all active Vagrant environments on the system for the currently logged in user.

Ref:

https://www.vagrantup.com/docs/cli/

Thursday, December 1, 2016

Connection to SVN on Win 10 machine with DirectAccess

 There are 2 svn connectors:
  1. SVN Kit
  2. JavaHL Native
Tortoise and Eclipse plugins for SVN by default use JavaHL and that does not work over DA by default!
Direct Access goes over IPv6.
Subclise for Eclipse can be set to use SVN Kit or JavaHL as client.
By default SVN Kit goes over IPv6 but tortoise is using JavaHL and those two are incompatible. Errors like

revert C:/projects/internal/backoffice-sso
    svn: E200030: Index not exists: I_NODES_MOVED
    Index not exists: I_NODES_MOVED
  
or
  
An internal error occurred during: "Refresh SVN status cache".
Can't overwrite cause with org.tmatesoft.svn.core.SVNException: 
svn: E155010: The node 'zzz_project' was not found.

Tortoise SVN

Get version that supports IPv6.
Latest version, 1.9.5 does not have ipv6 version and does not work!

Eclipse

Download and install SlikSVN (https://sliksvn.com/download/)
Install Subclipse in Eclipse via update site, I have used version 4.2.x where update site is https://dl.bintray.com/subclipse/releases/subclipse/4.2.x/
After, verify SVN interface that is in use (Preferences - type SVN) is SilkSvn.
Subclipse 1.10.13 does not use SlikSVN as connector! I guess versions are incompatible: Subclipse uses JavaHL 1.9.3 and installed SlikSvn uses 1.9.4

Resources

Wednesday, October 5, 2016

SSO using SAML

Single Sign On using Security Assertion Markup Language

Few options

Identity Provider (IDP) is used for authentication purposes only. It is replacing login screen :)
Service Provider (SP, application) will do authorization by reading roles from LDAP/database...
or
IDP will be used for authentication and authorization.
Problem with this approach is that SP does not know when role changes.

Session information can be stored using cookies on SP and IDP domain, so IDP can verify if user user is already logged on another SP.

Flow:

  1. User comes to SP (User is not logged. SP and IDP does not have any information about user)
  2. There is no session on SP for this user and user is redirected to IDP
  3. IDP authenticate user and send SAML response to SP
  4. SP validates SAML response and reads roles from datasource and the session is established
  5. User comes to SP2 (another application)
  6. SP2 does not have a session and asks IDP about this user.
  7. IDP knows this user has session so user is not provided with login screen. IDP reads data from datasource and returns SAML response to SP2
  8. SP2 validates SAML response and reads roles from LDAP
  9. User has seamlessly logged to SP2
Handle roles and password changes on SP.

IDP notes

IdP only reads, never having any sort of admin access. This helps security ­wise, knowing that authentication system can't write or retrieve sensitive information.

Common problems

Problem

DEBUG (SAMLProcessingFilter.java:99) - Incoming SAML message is invalid
org.opensaml.ws.security.SecurityPolicyException: Validation of protocol message signature failed

Solution

Verify that SP and IDP have proper metadata.

Problem

14:54:00.798 [http-nio-8082-exec-6] DEBUG (SAMLProcessingFilter.java:99) - Incoming SAML message is invalid
org.opensaml.ws.security.SecurityPolicyException: Validation of protocol message signature failed
at org.opensaml.common.binding.security.SAMLProtocolMessageXMLSignatureSecurityPolicyRule.doEvaluate(SAMLProtocolMessageXMLSignatureSecurityPolicyRule.java:138)
at org.opensaml.common.binding.security.SAMLProtocolMessageXMLSignatureSecurityPolicyRule.evaluate(SAMLProtocolMessageXMLSignatureSecurityPolicyRule.java:107)
at org.opensaml.ws.security.provider.BasicSecurityPolicy.evaluate(BasicSecurityPolicy.java:51)
at org.opensaml.ws.message.decoder.BaseMessageDecoder.processSecurityPolicy(BaseMessageDecoder.java:132)
at org.opensaml.ws.message.decoder.BaseMessageDecoder.decode(BaseMessageDecoder.java:83)
at org.opensaml.saml2.binding.decoding.BaseSAML2MessageDecoder.decode(BaseSAML2MessageDecoder.java:70)
at org.springframework.security.saml.processor.SAMLProcessorImpl.retrieveMessage(SAMLProcessorImpl.java:105)

Solution

Add IDP public key for signing messages to java key store. It can be found in incoming saml message from IDP.

http://stackoverflow.com/questions/23059203/http-status-401-authentication-failed-incoming-saml-message-is-invalid-with

Problem

InResponseToField of the Response doesn't correspond to sent message

Log
2016-10-26 12:33:20,159 DEBUG PROTOCOL_MESSAGE,http-nio-8080-exec-4:74 -
<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://mercurybi-local:8080/mercurybi/saml/SSO" Destination="https://authstack/saml2.0/sso" ForceAuthn="false" ID="a293907a4b8ed0d21iggb0ci9dc0bbb" IsPassive="false" IssueInstant="2016-10-26T10:33:20.100Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0">
   <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">SAMARA_SP</saml2:Issuer>
</saml2p:AuthnRequest>

2016-10-26 12:33:22,427 DEBUG PROTOCOL_MESSAGE,http-nio-8080-exec-5:113 -
<?xml version="1.0" encoding="UTF-8"?><samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" Destination="http://mercurybi-local:8080/mercurybi/saml/SSO" ID="_4981b4a45c61a289809108b15d7c401bb2c0bcdae5" InResponseTo="a293907a4b8ed0d21iggb0ci9dc0bbb" IssueInstant="2016-10-26T10:33:20Z" Version="2.0">
   <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://authstack</saml:Issuer>
   <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:SignedInfo>

  2016-10-26 12:33:22,698 DEBUG HttpSessionStorage,http-nio-8080-exec-5:117 - Message a293907a4b8ed0d21iggb0ci9dc0bbb not found in session A9C98F53D692EDFA486D96FB3D9F67C6
2016-10-26 12:33:22,702 DEBUG SAMLAuthenticationProvider,http-nio-8080-exec-5:98 - Error validating SAML message
org.opensaml.common.SAMLException: InResponseToField of the Response doesn't correspond to sent message a293907a4b8ed0d21iggb0ci9dc0bbb

Solution

<bean id="contextProvider" class="org.springframework.security.saml.context.SAMLContextProviderImpl">
  <property name="storageFactory">
    <bean class="org.springframework.security.saml.storage.EmptyStorageFactory"/>
  </property>
</bean>

Problem and Solution

Application is hosted on 2 different machines using different domains.
IDP manages to return proper domain name based on following rules

  1. read where to return in SP metadata
  2. if AssertionConsumerServiceURL field is present in SAML request use that one


<?xml version="1.0" encoding="UTF-8"?>

<saml2p:AuthnRequest
    AssertionConsumerServiceURL="http://app.samara.hr:8080/app/saml/SSO"
    Destination="https://myIDP/saml2.0/sso" ForceAuthn="false"
    ID="a4bi2g9cj906hj4429i0b0413h5aji4" IsPassive="false"
    IssueInstant="2016-11-03T13:57:40.212Z"
    ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
    Version="2.0" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
    <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">SAMARA-SP</saml2:Issuer>
</saml2p:AuthnRequest>

Logout and SingleLogout feature

What will be URL used for redirects (if that option is used) update SP metadata:

<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://mydomain.samara.hr/myApp/saml/SingleLogout"/>

Send SAML request via POST

To be sure POST is used:

@Bean
public WebSSOProfileOptions defaultWebSSOProfileOptions() {
final WebSSOProfileOptions webSSOProfileOptions = new WebSSOProfileOptions();
webSSOProfileOptions.setIncludeScoping(false);
webSSOProfileOptions.setBinding(SAMLConstants.SAML2_POST_BINDING_URI);
return webSSOProfileOptions;
}

Ref:

SWITCH - Demo
okta - SAML
SAML Security Cheat Sheet
Spring Security SAML
Spring SAML - Troubleshooting common problems
Can one SP metadata file be used for 5 separate SPs running the same application

Wednesday, August 17, 2016

Gradle

generate dependency tree

$ ./gradlew dependencies > dep.txt


generate dependency tree and refresh dependencies

$ ./gradlew dependencies > dep.txt --refresh-dependencies
The --refresh-dependencies option tells Gradle to ignore all cached entries for resolved modules and artifacts.

Ref: Listing project dependencies

create java project

$ gradle init --type java-application
More info at Build Init Plugin
Clean build.gradle file

eclipse - download sources and javadoc

apply plugin: 'java'
apply plugin: 'eclipse'

eclipse {
    classpath {
        downloadJavadoc = true
        downloadSources = true
    }
}

repositories {
    mavenCentral()
    mavenLocal()
}

$ gradle cleanEclipse eclipse

If mavenLocal() is present in your repositories, don't forget to put it at the bottom of the list.


add test sources from one project to second in multiproject environment

testCompile project(':sub-project').sourceSets.test.output

publish to local repository

$ ./gradlew publishToMavenLocal

Ref

https://stackoverflow.com/questions/28404149/how-to-download-javadocs-and-sources-for-jar-using-gradle-2-0

Tuesday, August 9, 2016

Angular.JS notes

Notes

AngularJS is a JavaScript framework. It can be added to an HTML page with a <script> tag.
AngularJS extends HTML attributes with Directives, and binds data to HTML with Expressions.




A Directive is a marker on a HTML tag that tells Angular to run or reference some JavaScript code.
Controllers are where we define our app’s behavior by defining functions and values.
Modules – where our application components live
Expressions – how values get displayed within the page

AngularJS Example

index.html
<!DOCTYPE html>
<html ng-app="gemStore">
  <head>
    <script type="text/javascript" src="angular.min.js"></script>
    <script type="text/javascript" src="app.js"></script>
  </head>
  
<body ng-controller="StoreController as store">
<div ng-repeat="product in store.products">
<h1>{{product.name}}</h1>
<h2> ${{product.price}}</h2>
<p> {{product.description}}</p>
<button ng-show="product.canPurchase">Add to Cart</button>
</div>
</body>
</html>

app.js
(function() {
var app = angular.module('gemStore', []);

app.controller('StoreController', function() {
// store data in the controller
this.products = gems;
});

var gems = [
{ name: 'Azurite', price: 2.95, description: 'Dobar za prodaju....', canPurchase : true },
{ name: 'Bloodstone', price: 5.95, description: 'Ne mozes kupiti', canPurchase : false },
{ name: 'Zircon', price: 3.95, description: 'ZZZZZZ', canPurchase : true }
];

})();

Ref


Wednesday, May 25, 2016

Tomcat notes

Configure tomcat to expose files from disk

In tomcat conf/server.xml add at the bottom before </Host>:

 <Context path="/results"
                 docBase="/opt/prov/rdisk/manufacturer_results"
                 debug ="99"
                 reloadable="true">
 </Context>


In you application properties you can define:

#where to save files
path_file=/opt/prov/rdisk/manufacturer_results/{0}_name.csv
#url to fetch file
url_file=http://machine:8080/results/{0}_error.csv

Tomcat exposes files found on those places on disk.
You can reach them via http.

Thursday, April 7, 2016

Quartz with Spring - Java configuration

In my previous post Quartz with Spring and embedded database I have used xml to configure spring 3 with quartz 1.8.

Now I will configure spring 4.2 with quartz 2.2.2 using Java configuration. I am using quartz in cluster.

Java configuration class

@Configuration
@ComponentScan({ "hr.samara.job" })
public class QuartzConfig
{

@Autowired
private DataSource dataSource;
@Autowired
private JpaTransactionManager transactionManager;
@Autowired
private Environment env;

@Autowired
private SimOperation simOperation;

@Bean
public SchedulerFactoryBean scheduler()
{
SchedulerFactoryBean scheduler = new SchedulerFactoryBean();
scheduler.setConfigLocation(new ClassPathResource("quartz.properties"));

scheduler.setDataSource(dataSource);
scheduler.setTransactionManager(transactionManager);

// inject simOperation - spring bean in job
Map<String, Object> map = new HashMap<>();
map.put("simOperation", simOperation);
scheduler.setSchedulerContextAsMap(map);


scheduler.setTriggers(blockSimTrigger().getObject());
return scheduler;
}

@Bean
public CronTriggerFactoryBean blockSimTrigger()
{
CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
cronTriggerFactoryBean.setJobDetail(blockSimJob().getObject());
cronTriggerFactoryBean.setCronExpression(env.getProperty("job.blockSim.cron"));
cronTriggerFactoryBean.setMisfireInstructionName("MISFIRE_INSTRUCTION_FIRE_ONCE_NOW");
return cronTriggerFactoryBean;
}

@Bean
public JobDetailFactoryBean blockSimJob()
{
JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean();
jobDetailFactory.setJobClass(BlockSimJob.class);
jobDetailFactory.setDescription("call sim block");
return jobDetailFactory;
}

}


Job class

@DisallowConcurrentExecution
public class BlockSimJob extends QuartzJobBean
{

private transient SimOperation simOperation;

@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException
{
simOperation.blockSim();
}

public void setSimOperation(SimOperation simOperation)
{
this.simOperation = simOperation;
}

}


Ref:
http://www.baeldung.com/spring-quartz-schedule