12/28/15

Using Spring Session for Securing RestFull webservice in Spring MVC web application

Getting started with Spring Security, Spring Session and Redis

You want to build a scalable cloud ready application? Great! Let’s have a look how to build a server Spring Boot REST endpoint and secure it with stateless Spring Security. We want to authenticate every request with basic authentication OR with a token when the user has sent its credentials once. When a user authenticates with basic authentication we store a session ID in Redis with Spring Session and return it to the user to in the following requests.
If you haven’t heard of Spring Boot before, be sure to read up on it on: What are Microservices or Build your own Linkshortener API.

Standard HTTP Session in Java (JEE)

There are a quite a few shortcommings in Application Servers HTTP session implementations that we want to avoid:
  • Have you ever tried to enable HTTP Sessions replication and clustering on Tomcat? It’s not an easy thing to do.
  • Sessions are tightly coupled with the HTTP protocol, but there are other scenario’s where you’d like to access the session like when using JMS. Or keeping sessions alive when using WebSockets.
  • How do you go about when you want to allow users to have multiple sessions, one for each tab (like in Gmail)?

Get started with Spring Session

With Spring Session all these issues are solved without any effort. This makes it easy to scale your cloud application since it doesn’t need to store sessions on disk anymore. As long as your Application Server uses a HttpSession, you can get started in a couple of easy steps. Let’s get started with a simple Spring Boot application with Spring Security for securing a RESTful service and store sessions in Redis:
Application.java
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
pom.xml

  
    org.springframework.session
spring-session-data-redis 1.0.1.RELEASE org.springframework.boot spring-boot-starter-security org.springframework.boot spring-boot-starter-web
This would give us a working web application, that is secured by default because we include the Spring Boot Security Starter dependency. For ease of use we’ll start an in-memory database with one user present to use for authentication. We will authenticate every request with Basic Authentication and also create a HeaderHttpSessionStrategyto tell Spring to use a X-Auth-Token header for retrieving the session.
SecurityConfiguration.java
@Configuration
@EnableWebSecurity
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder builder) throws Exception {
        builder.inMemoryAuthentication()
            .withUser("user").password("password").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .requestCache()
            .requestCache(new NullRequestCache())
            .and()
            .httpBasic();
    }

    @Bean
    public HttpSessionStrategy httpSessionStrategy() {
        return new HeaderHttpSessionStrategy();
    }
}

Hello Redis - a NoSQL key-value database

We don’t want to to reauthenticate every request by going to the database, this is why we will store a Session ID in Redis. This Session ID will be passed to the client after authenticating the first time, and from then on it can send this as a request header for all subsequent requests which will verify the user is authenticated.
If you look at the Spring Session documentation you’ll see that they always use an@EmbeddedRedisConfiguration to start an embedded Redis instance, it’s pretty unclear that this is NOT yet available in Spring Session. They included some addtional classes in all their examples to get this to work, we’ll have to wait for Spring Session GitHub ticketuntil this will actually be implemented in Spring itself. For now I have a simple Configuration class that starts an instance without any customization, by using the Embedded redis depdency.
pom.xml

    com.github.kstyrc
embedded-redis 0.6
EmbeddedRedisConfiguration.java
@Configuration
@EnableRedisHttpSession
public class EmbeddedRedisConfiguration {
    private static RedisServer redisServer;

    @Bean
    public JedisConnectionFactory connectionFactory() throws IOException {
        redisServer = new RedisServer(Protocol.DEFAULT_PORT);
        redisServer.start();
        return new JedisConnectionFactory();
    }

    @PreDestroy
    public void destroy() {
        redisServer.stop();
    }
}
And to finish it off we’ll expose one endpoint to actually verify the outcome of our security configuration.
UserController.java
@RestController
public class UserController {

    @RequestMapping("/api/users")
    public String authorized() {
        return "Hello Secured World";
    }
}
We can verify the behaviour of our application by using curl:
curl -v http://localhost:8080/api/users
< HTTP/1.1 401 Unauthorized
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< WWW-Authenticate: Basic realm="Realm"
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Thu, 21 May 2015 21:44:26 GMT
Now let’s do that again, but this time add Basic Authentication with our in-memory database user:
curl -v http://localhost:8080/api/users -u user:password
< HTTP/1.1 200 OK
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< x-auth-token: ef555ceb-1c77-4fdd-8e42-e04399fe5b95
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 19
< Date: Thu, 21 May 2015 21:47:30 GMT
We send our credentials and received a x-auth-token in the response, which we can use in the following requests to authenticate:
curl -v http://localhost:8080/api/users -H "x-auth-token: ef555ceb-1c77-4fdd-8e42-e04399fe5b95"
< HTTP/1.1 200 OK
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 19
< Date: Thu, 21 May 2015 21:50:24 GMT

11/25/15

Tutorial to create Drill Down Reports using Jasper Reports

Link demo: https://www.youtube.com/watch?v=w6fq1kdeElY
All in one images:
Step 1: open Hyperlink of a field in main report
Step 2: Select Link Target = Self   ;   Slect Link Type = ReportExecution
Step 3: Find on Target Report (DrillDown Report) two main input-parameters to open the report via link from main report. (in my case the drilldown report just need one parameter (requestID) and the Path will be got from Properties popup window of target report.


Now you can cook your linking report (main report) with all what I show here:




10/20/15

Ubuntu: Remmina Copy and Paste not Working

POSSIBLE WORKAROUND:
Ok, I was reading the README in the new source code. I got to the line were it says: install dependencies:
$ sudo apt-get install cmake intltool libgtk-3-dev libssh-dev libavahi-ui-gtk3-dev libvte-2.90-dev libxkbfile-dev
Once I installed that, I tested the old version I am currently using, Remmina 0.9.99.1 runs, (as it did) but copy paste functionality has resumed!
The source for version 1 still failed to compile, that's a bummer, but as long as i can copy and paste in a relatively new version, I'm ok with this solution. Try it if you like. I'll look into compiling the new version later.
At this point, the bug would seem to be a dependency issue. perhaps there are log files that will give more information about this.
A successful work-around (for me) was achieved by running the following (in one command-line):
sudo apt-add-repository ppa:remmina-ppa-team/remmina-next ; sudo apt-get update ; sudo apt-get install remmina remmina-plugin-rdp
You may have to reboot after this to see the new version of Remmina that this installs (I did).

10/14/15

STS shortcuts

Shortcuts
Description
“sysout” + Crtl + Space
Quick System.out.println()
Alt + Enter
Open project properties
Alt + Shift + R
Rename
Alt + Shift + S
Context menu with possible actions
Alt + Shift + S, C
Generate constructor from superclass
Alt + Shift + S, H
Generate hashCode() and equals()
Alt + Shift + S, O
Generate constructor using fields
Alt + Shift + S, R
Generate getters and setters
Alt + Shift + S, S
Generate toString()
ALT <- or ALT ->
Go to previous or next edit positions from editor history list
ALT SHIFT Z
Enclose block in try-catch
Crtl + Alt + Down arrow
Copy current line below
Crtl + D
Delete current line
Crtl + I
Indent lines
Crtl + L
Go To Line Number
Crtl + N
Open New file/project wizard
Crtl + Shift + C
Add / remove single line comments
Crtl + Shift + F
Format code
Crtl + Shift + L
Quick Text Search (STS only)
Crtl + Shift + O
Organize import statements
Crtl + Space
Autocomplete
Crtl + W
Close currently viewed file
CTRL /
Comment a line
CTRL E
Open a file (editor) from within the list of all open files
CTRL H
Java search in workspace
CTRL M
Maximize editor
CTRL O
List all methods of the class and again CTRL O lists including inherited methods
CTRL PAGE UP or PAGE DOWN
Navigate to previous or next file from within the list of all open files
CTRL SHIFT G
Search for current cursor positioned word reference in workspace
CTRL SHIFT P
Go to the matching parenthesis
CTRL SHIFT R
Open a resource
CTRL SHIFT U
Find reference in file
CTRL T
Show inheritance tree of current token.
F3
Go to the declaration of the variable.
F4
Show type hierarchy of on a class.
Shift + Enter
Insert blank line after current line
SHIFT F2
Show Javadoc for current element

10/12/15

Simply Singleton

An alternative thread-safe singleton implementation

Example 7 lists a simple, fast, and thread-safe singleton implementation:

Example 7. A simple singleton

public class Singleton {
   public final static Singleton INSTANCE = new Singleton();
   private Singleton() {
         // Exists only to defeat instantiation.
      }
}
The preceding singleton implementation is thread-safe because static member variables created when declared are guaranteed to be created the first time they are accessed. You get a thread-safe implementation that automatically employs lazy instantiation; here's how you use it:
Singleton singleton = Singleton.INSTANCE;
      singleton.dothis();
      singleton.dothat();
      ...
Of course, like nearly everything else, the preceding singleton is a compromise; if you use that implementation, you can't change your mind and allow multiple singleton instances later on. With a more conservative singleton implementation, instances are obtained through a getInstance() method, and you can change those methods to return a unique instance or one of hundreds. You can't do the same with a public static member variable.

8/19/15

Data codes related to 'LDAP: error code 49' with Microsoft Active Directory

Data codes related to 'LDAP: error code 49' with Microsoft Active Directory

Technote (troubleshooting)


Problem

When IBM® WebSphere® Portal accesses the LDAP (in this case Microsoft® Active Directory), either to start the server or during configuration tasks, "LDAP: error code 49" can be encountered.

Symptom

Generally, error references SECJ0369E and SECJ0055E will be generated in the SystemOut.log. There are, however, various root causes that can be derived from the values that follow the initial description. An example is shown below.
From SystemOut.log:

[date/time] 0000000a LdapRegistryI A SECJ0419I: The user registry is currently connected to the LDAP server ldap://:389.
[date/time] 0000000a LTPAServerObj E SECJ0369E: Authentication failed when using LTPA. The exception is [LDAP: error code 49 - 80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 775, vece ].
[date/time] 0000000a distContextMa E SECJ0270E: Failed to get actual credentials. The exception is javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 775, vece ]
at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3005)


In this case, validate-ldap is the config task that was failing, and from the ConfigTrace.log we see:

action-validate-ldap-was-admin-user:
[ldapcheck] ###########################
[ldapcheck] ldapURL : :389
[ldapcheck] ldapUser : CN=wasadmin,OU=WebspherePortal,OU=Service Accounts,DC=select,DC=corp,DC=sem
[ldapcheck] ldapPassword : *********
[ldapcheck] ldapSslEnabled : false
[ldapcheck] javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 775, vece ]
[ldapcheck] ERROR: 4
[ldapcheck] Invalid or insufficient authorization privileges.
Target finished: action-validate-ldap-was-admin-user

Cause

The error shown below is similar each time there is an LDAP authentication issue. 
    "The exception is [ LDAP: error code 49 - 80090308: LdapErr: DSID-0Cxxxxxx, comment: AcceptSecurityContext error, data xxx, vece ]."

However, there are several values that can indicate what LDAP function is causing the issue. Here are some general references for Microsoft Active Directory:

The AD-specific error code is the one after "data" and before "vece" or "v893" in the actual error string returned to the binding process

525user not found
52einvalid credentials
530not permitted to logon at this time
531not permitted to logon at this workstation
532password expired
533
534
account disabled
The user has not been granted the requested logon type at this machine
701account expired
773user must reset password
775user account locked

     
Common Active Directory LDAP bind errors: 

80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 525, v893
HEX: 0x525 - user not found 
DEC: 1317 - ERROR_NO_SUCH_USER
 (The specified account does not exist.)
NOTE: Returns when username is invalid.

80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 52e, v893
HEX: 0x52e - invalid credentials 
DEC: 1326 - ERROR_LOGON_FAILURE
 (Logon failure: unknown user name or bad password.)
NOTE: Returns when username is valid but password/credential is invalid. Will prevent most other errors from being displayed as noted.

80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 530, v893
HEX: 0x530 - not permitted to logon at this time 
DEC: 1328 - ERROR_INVALID_LOGON_HOURS 
(Logon failure: account logon time restriction violation.)
NOTE: Returns only when presented with valid username and password/credential.

80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 531, v893
HEX: 0x531 - not permitted to logon from this workstation 
DEC: 1329 - ERROR_INVALID_WORKSTATION
 (Logon failure: user not allowed to log on to this computer.)
LDAP[userWorkstations: ]
NOTE: Returns only when presented with valid username and password/credential.

80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 532, v893
HEX: 0x532 - password expired 
DEC: 1330 - ERROR_PASSWORD_EXPIRED
 (Logon failure: the specified account password has expired.)
LDAP[userAccountControl: ] - PASSWORDEXPIRED
NOTE: Returns only when presented with valid username and password/credential.

80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 533, v893
HEX: 0x533 - account disabled 
DEC: 1331 - ERROR_ACCOUNT_DISABLED 
(Logon failure: account currently disabled.)
LDAP[userAccountControl: ] - ACCOUNTDISABLE
NOTE: Returns only when presented with valid username and password/credential.

80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 701, v893
HEX: 0x701 - account expired 
DEC: 1793 - ERROR_ACCOUNT_EXPIRED 
(The user's account has expired.)
LDAP[accountExpires: ] - ACCOUNTEXPIRED
NOTE: Returns only when presented with valid username and password/credential.

80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 773, v893
HEX: 0x773 - user must reset password 
DEC: 1907 - ERROR_PASSWORD_MUST_CHANGE 
(The user's password must be changed before logging on the first time.)
LDAP[pwdLastSet: ] - MUST_CHANGE_PASSWD
NOTE: Returns only when presented with valid username and password/credential.

80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 775, v893
HEX: 0x775 - account locked out 
DEC
1909 - ERROR_ACCOUNT_LOCKED_OUT (The referenced account is currently locked out and may not be logged on to.)
LDAP[userAccountControl: ] - LOCKOUT
NOTE: Returns even if invalid password is presented

The DEC: values are not presented in Portal logs; however, review of LDAP activity combined with analysis of SystemOut.log and relevant configuration tasks can help narrow down the root cause.

Resolving the problem

NOTE: This document is not meant to provide a solution to any LDAP errors. Since the full LDAP error described in the DEC statement is not captured in the Portal logs, this document can be used to associate the errors found in the SystemOut.log to common LDAP errors for MSAD.
Use the codes above to verify the settings and users in LDAP.