Showing posts with label web applications. Show all posts
Showing posts with label web applications. Show all posts

Thursday, 1 June 2017

flexibleJDBCRealm

I have recently changed my security realm settings, and I thought I'd document them here.

I'm still using the flexibleJDBCRealm1 as I've documented in previous blogs2,3.

In the Glassfish administration console, under Configurations -> server-config -> Security -> Realms -> myRealm, the settings are now as follows.
NameValueDescription
datasource.jndijdbc/mydbthe data source to my database
jaas.contextflexibleJdbcRealm
password.digestSHA-512I have upgraded from SHA1 to SHA2, which seems more secure
password.encodingHEX:128See note below
sql.groupsselect groupid from mmv_groups where name in (?)using a database view, makes it easier to change table layout without effecting the securityrealm
sql.passwordselect password from mmv_users where name in (?)same as above

Note

The SHA-512 encoding always creates 128 characters as the hash.

However, in the source code of the flexibleJDBCRealm, this hash is converted from a byte[] into a hexadecimal string by means of a call "new BigInteger(1, aData).toString(16);".

This effectively means that if the byte[] starts with one or more "0"s, these are removed in the BigInteger call leaving you with a hash that is less than 128 characters.

This is why I need to use "HEX:128", instead of just "HEX".

MariaDB/MySQL

The values are easily verifiable in the database.

I can just do a
SELECT SHA2(usertable.password, 512) from usertable where user='mrbear';

It should yield the exact same result as the encryption function of the flexibleJDBCRealm.

References

[1] FlexibleJDBCRealm
http://flexiblejdbcrealm.wamblee.org/site/
[2] Security Realms in Glassfish
http://randomthoughtsonjavaprogramming.blogspot.nl/2016/04/security-realms-in-glassfish.html
[3] Glassfish Security Realms
http://randomthoughtsonjavaprogramming.blogspot.nl/2014/10/glassfish-security-realms.html
[4] Installation instructions
http://flexiblejdbcrealm.wamblee.org/site/documentation/snapshot/installation.html

Friday, 19 February 2016

Front end update: Angular 2.0 & HTTP/2

I have taken up learning Angular, yet it seems that a new angular is being prepared, Angular 21. Angular 2 seems to be a complete rewrite, and has a very different architecture. For one thing, it can work with ECMAScript 6 and TypeScript.

Luckily, I managed to be at a small session regarding Angular 2 at Quintor, today, Thursday the 18th of February 2016.2.

As a matter of fact, I am writing this blog in the train home.

HTTP/2

The speaker was Martijn van Campenhout of Quintor. The first presentation was regarding the new HTTP/2 protocol (officially released in May 2015), which is rapidly replacing the old HTTP/1.1 version (released in 1996). It is based on the SPDY implementation developed by Google in 2010 and officially submitted for standardisation.

Statistics shown by Mozilla indicate that an decrease of pageload times of 2.2 seconds, results in an increase of Downloads by about 15%.3 4

Old tips and tricks

The old tips and tricks that are used to deal with the defficiencies of HTTP/1.1 and the lack of bandwith and troubles with latency were:
  • combining files as much as possible
  • inlining everything
  • minifying everything
  • domain sharding
  • using sprite files
  • define critical CSS and JS files
  • using GZIP
These different tactics are used to make sure the Webbrowser has to do a minimum number of requests and does not need to get a lot of data to the user.

It seems the Chrome browser development tools has excellent support for simulating bad connections or large latency, using a variety of set network connection types.

Another common tactic was to display/render only those parts of the web page that are visible to the user. Once the user starts scrolling, the parts that scroll into the viewscreen of the user are downloaded and rendered. This is called "the Fold"5, and is a common DTP term.

There was a most impressive demonstration, where a picture consisting of about 100 smaller pictures was being shown, with a one second delay (latency) between the request and the response for a smaller picture. The difference between HTTP/1.1 and HTTP/2 was very big. Where the Browser only allows 8 concurrent connections with HTTP/1.1 causing a severe bottleneck, a single connection using HTTP/2 was more than enough to show the entire picture in about a second.

The tactics used for HTTP/2 can be summed up as follows:
Multiplexing
different Streams of data (files, css, images, html, javascript) across the same HTTP connection
Priority
allowing a setting of priority based on content. For example that the big logo should be loaded first, and the little icons at the bottom of the page last.
Binary Headers
easier and quicker to parse, fixed length, unambiguous
HPACK
In the past headers were not compressed, this has now changed.
Server push
server remembers the combination of files requested. One file request will trigger the others automatically.

This is also the first time that I heard the term CRIME, "Compression Ratio Info-leak Made Easy". Basically it boils down to a man-in-the-middle-attack, adding stuff to a message to see if it increased the compressed file. If it does not, the item added already was part of the file, and he has learned something valuable regarding the message.

The HTTP/2 is already incorporated in Apache server, NGINX. Servlet specification 4.0 of Java EE 8 will have support for it (JSR-369).

Criticisms

There were some criticisms regarding HTTP/2, though.

It seems the HTTP/2 might just be available only using HTTPS. The configuring of priority and server push needs to be done on the backend right now and cannot be controlled by the webdeveloper. This causes a tight coupling between front end and back end, which most people (including me) might not like.

All these optimalisations mean absolutely nothing, if your resources (html files, images, etc) are retrieved from many different servers.

Note: the effect of HTTP/2 is also that the old tips and tricks are not only useless, but can actually hamper the responsiveness of the website. An example of this is caching.

Angular 2

The speaker, Rachèl Heimbach, went quite fast through his presentation, which means we had time for two presentations in stead of one. On the other hand, it did require an inordinate amount of attention and knowledge of Angular/JavaScript/TypeScript to follow.

Angular 2 uses both ECMAScript 6 and TypeScript.

Some of the most important features6 of ECMAScript 6 that will return when you are attempting Angular 2:
  • class
  • import
  • export
  • private namespaces (without export and import, everything is by default off limits)
  • default values (used when parameters are omitted in the function call)
  • lambdas (no longer do we require the use of "var self = this;".
Benefits of using TypeScript in angular 2 are as follows:
  • safe typing, makes refactoring and debugging a whole lot easier
  • @Decorators, makes injection and adding behaviour generically a whole lot easier
Instead of the familiar services, factories and controllers of Angular 1, Angular 2 has simplified this a bit. Angular 2 basically consists of only Web components (that make up your pages/views/etc) and singleton injectors (that can take the place of your controllers, factories and services.) As you can see there is no longer a distinction necessary.

Some more enhancements:
  • ChangeDetection
  • ViewEncapsulation (with a shadow dom)
  • Provide function
  • ngUpgrade thing
It is possible to upgrade an Angular 1 application piece-by-piece or add Angular 2 components to it. The other way around is also possible.

Notes

HTTP/2 seems to be more and more widely supported. Angular 2 is still in the beta phase, however, it seems to be fairly stable. Unfortunately, it is currently not recommended for production use. However, the presentation did point out that in order to make the task of porting your application from Angular 1 to Angular 2 less onerous, it might be a good bet to start by designing the new parts of your Angular 1 application according to the Angular 2 style.

A question was raised on whether or not you should use Angular 2 at all. It seems Google will support Angular 1 for as long as there is a market for it. I heard that they measure the traffic to the two websites (Angular 1 and Angular 2) to determine interest. I got the impression from the presentation that Angular 1 has slowly been moving towards the new Angular 2 way of doing things.

Performance wise, Angular 2 is a step in the right direction. Keeping new Angular 2 in mind, whilst working on an Angular 1 application seems to be a very safe bet. If the need will arise in the future that a port is required, at least it will not be as herculean a task as first thought.

References

[1] Angular 2
https://angular.io/
[2] Quintor - Front end update: Angular 2.0 & HTTP/2
https://www.quintor.nl/sessie-front-end-update/
[3] Webpage testing
http://www.webpagetest.org
[4] Can I use?
http://www.caniuse.com
[5] Wikipedia - Above the fold
https://en.wikipedia.org/wiki/Above_the_fold
[6] ES6 Features
http://www.es6-features.org

Sunday, 19 October 2014

Glassfish Security Realms

The JDBCRealm

In the Glassfish Administration Console, go to Configurations -> server-config -> Security -> Realms -> and select "New".

We're going to choose com.sun.enterprise.security.ee.auth.realm.jdbc.JDBCRealm.

The jaas.context name of the new realm is "jdbcRealm".

A jdbcRealm needs both a user table and a group table. The group table should store both userids as well as groupids. In other words,
  • the group table doesn't only contain groups, and
  • has a composite primary key, consisting of userid and groupid.

Database Schema

The user table is called "mm_admin" in my case, and the groups table is called "mm_admin_mm_groups".

I have created the "mm_groups" table to store extra information for groups, but that table is ignored by the jdbcRealm.

Some serious disadvantages of the jdbcRealm are:
  • groups are cached, which means if a user changes groups, the Glassfish Server needs to be rebooted.
  • flexibility is about zero, for instance if I have an expiration date attached to my usertable, I'm out of luck.
All this causes me to look elsewhere, namely towards the flexibleJDBCRealm5

The flexibleJDBCRealm

The great advantage of the flexibleJDBCRealm is that you can add SQL queries that are run to retrieve passwords and groups.

Instructions

Well, according to instructions found here6, you have to:
  1. download the flexiblejdbcrealm-deploy-1.2-all.jar
  2. put it into glassfish/domains/domain1/lib directory
  3. change glassfish/domains/domain1/config/login.conf to add
    flexibleJdbcRealm {
    org.wamblee.glassfish.auth.FlexibleJdbcLoginModule required;
    };
  4. reboot the glassfish
  5. In the Glassfish Administration Console, go to Configurations -> server-config -> Security -> Realms -> and select "New"
  6. enter the class name org.wamblee.glassfish.auth.FlexibleJdbcRealm
  7. set the properties, for example like in the image above.

Properties

The properties that can be entered could use a little more explaining compared to what is available at [6].
password.digest
uses MessageDigest(String algorithm). Possible values are "PLAIN", "MD2", "MD5", "SHA-1", "SHA-256", "SHA-384" and SHA-512.
password.encoding
the encoding, I find HEX to be the most useful. Possibile values are "TEXT", "HEX" and "BASE64". A variation of "HEX" is "HEX:<digits>", for example "HEX:40". This padds the beginning of the encoding with zeros to reach the length required. For example MySQL itself always creates passwords using the SHA() function to 40 hex digits also padding the beginning with zeros.
sql.groups
select groupid from mm_admin_mm_groups where name in (?)
sql.password
select passwd from mm_admin where name in (?) and validuntil > now()
jaas.context
flexibleJdbcRealm
datasource.jndi
of course, the connection string to the database
NOTE: he's complaining about setting properties in the realm with a = in them. So I had to go back to an "in (?)" construction for the SQL queries.

Logging

In glassfish/domains/domain1/config/logging.properties, add: org.wamblee.level=FINEST.

Application Configuration

My web.xml would look like thusly:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" 
    xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
             http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <security-constraint>
        <display-name>Administration</display-name>
        <web-resource-collection>
            <web-resource-name>Administration REST Resources</web-resource-name>
            <description/>
            <url-pattern>/resources/administration/*</url-pattern>
            <url-pattern>/administration/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <description/>
            <role-name>deputy</role-name>
        </auth-constraint>
    </security-constraint>
    <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>deputyRealm</realm-name>
    </login-config>
    <security-role>
        <description/>
        <role-name>deputy</role-name>
    </security-role>
</web-app>
My glassfish-web.xml looks like:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app 
    PUBLIC 
    "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" 
    "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">

<glassfish-web-app error-url="">
  <security-role-mapping>
    <role-name>deputy</role-name>
    <group-name>deputy</group-name>
  </security-role-mapping>
  <class-loader delegate="true"/>
  <jsp-config>
    <property name="keepgenerated" value="true">
      <description>Keep a copy of the generated servlet class' java code.</description>
    </property>
  </jsp-config>
</glassfish-web-app>
In this file you can create a mapping between security roles and groups.

Declarative Security

An example of declarative security using Annotations:
@DeclareRoles("deputy")
@RolesAllowed("deputy")
@Stateless
@Path("/administration/worldattributes")
public class WorldattributesBean extends AbstractFacade<Worldattribute>
{
This means the role definition in the web.xml can be removed.

In the example above, the security role is applied to the entire Bean, so for each method in the bean, instead of on each method that requires the role.

Programmatic Security

Unfortunately, some fine-grained security can only be done with programmatic means, for example determining if a person who has authenticated themselves owns a certain object that needs mutated upon. In my example, this info in a Rest service can be obtained through a SecurityContext:
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.Context;
...
@POST
@Override
@Consumes(
{
     "application/xml""application/json"
})
public void create(Worldattribute entity, @Context SecurityContext sc)
{
  itsLog.info("create");
  final String name = sc.getUserPrincipal().getName();

FAQ

I get WEB9102: Web Login Failed: com.sun.enterprise.security.auth.login.common.LoginException: Login failed: No LoginModules configured for flexibleJdbcRealm?
You forgot to add the entry to the login.conf as specified above.

References

[1] Oracle - Security in the Java EE Platform
http://docs.oracle.com/javaee/7/tutorial/doc/security-intro.htm
[2] The Java EE 7 Tutorial
Release 7 for Java EE Platform
[3] Oracle - Using the JDBC Realm for User Authentication
http://docs.oracle.com/javaee/6/tutorial/doc/glxgo.html
[4] Understanding Web Security
http://java.dzone.com/articles/understanding-web-security
[5] FlexibleJDBCRealm
http://flexiblejdbcrealm.wamblee.org/site/
[6] Installation instructions
http://flexiblejdbcrealm.wamblee.org/site/documentation/snapshot/installation.html