Sunrise near Sechtem

In the early Saturday morning I usually ride my bike, driving a few kilometers to a small village called Sechtem where I by some bread rolls for the week. On my way home, the sun rised above a stand alone house at the outskirts of Sechtem. I stopped my ride and fetched my camera out of the rucksack.

The best view had been gone a few seconds before I got my camera ready. But I still like that snapshot. Enjoy too.

JSF: import constants

With the current version of Java EE 8 / JSF 2.3 we can implement an internal navigation using enums. And this is what we use for Alumni’s [1] navigation. As an example we pick the forgot password link.

1 <div> 
2     #{msg.lblForgotPassword} 
3     <h:link value="#{msg.lblRequestPassword}" 
4           outcome="#{Page.RequestPassword.url()}"/>
5 </div>

Take a look onto line 4. Here the outcome is directly composed by the enum’s url. We simply use the enum like we do within a Java source file.

The page enum looks like this:

 1 public enum Page { 
 2 
 3    RequestPassword("/public/requestPassword"),
 4    <other pages here>
 5    ;
 6 
 7    private Page(String url) {
 8      _url = url;
 9    }
10   private final String _url;
11 
12   public String getUrl() {
13     return _url + ".xhtml";
14   }
15 
16   public String getRedirectUrl() {
17     return _url + ".xhtml?faces-redirect=true";
18   }
19   ...
20 }

Using an enum for the navigation decouples the page definition from the navigation targets within our source code (without any need for using a xml file to declare navigation cases). If we want to relocate the page, we only need to update the enum.

As a pre-requisite we need to tell the EL about our enum. That’s what the new importConstants tags comes into play for. Within the metadata we need to declare this tag in conjunction with the full class name.

1 <f:metadata>
2      <f:importConstants type="de.muellerbruehl.alumni.gui.enums.Page"/>
3 </f:metadata>

Although Alumni only imports enums, you may use the importConstants tag for any kind of constants.

Stay tuned!

 

 

[1] Alumni is the social web application I describe in my book

Custom Realm

Do you remember the requirements for secure passwords?
• We need an algorithm, which takes some time to calculate to prevent from brute force
attacks (or at least to reduce its chance to success). JdbcRealm allows to determine the
algorithm.
• We need to add a salt to every password to protect against rainbow tables. JdbcRealm
fails on this requirement.Authentication and Authorization

Here, a custom realm comes into play. It enables the developer to save the passwords in any
store with any algorithm of his choice. Such a custom realm might be vendor specific. The
following realm is developed for the GlassFish server. Please check, whether it is applicable
to your server.
First of all, we need to derive a custom realm from AppservRealm .

public class AlumniRealm extends AppservRealm {

@Override
 public String getAuthType() {
 return "alumniRealm";
 }

@Override
 public String getJAASContext() {
 return "alumniRealm";
 }

@Override
 public Enumeration getGroupNames(String username) {
 List<String> groups = new ArrayList<>();
 groups.add("member");
 groups.add("admin");
 return Collections.enumeration(groups);
 }

}

We need to override three methods. For AuthType and JAASContext this realm simply
returns its name. This is needed to identify this realm within the server’s configuration.
The intention of GroupNames is to provide all possible groups of the solution. For simplicity of this demonstration, all the names are coded within the method. This might be ok for an authentication realm which is used for a certain application. Even better, you might define the group names within some properties or get it from a database.
Next, we need a LoginModule which need to be derived from AppservPasswordLoginModule.

public class LoginModule extends AppservPasswordLoginModule {

@Override
 protected void authenticateUser() throws LoginException {
 if (!(_currentRealm instanceof AlumniRealm)) {
 throw new LoginException("Unexpected realm: "
 + _currentRealm.getClass().getSimpleName());
 }

String[] groups = obtainPermittedGroups(_username, _passwd);
 if (groups.length > 0) {
 commitUserAuthentication(groups);
 }
 }

private static final String BASE_URI = "http://localhost:8082/AlumniAccount/api";

String[] obtainPermittedGroups(String userName, char[] passwd) {
 Client client = ClientBuilder.newClient();
 WebTarget resource = client.target(BASE_URI)
 .path("Accounts")
 .path("login")
 .path(userName)
 .path(new String(passwd));
 String groups = resource.request(MediaType.APPLICATION_JSON).get(String.class);
 client.close();
 return groups.split(";");
 }

}

Within the login module we first check whether the current realm is the expected custom
realm. _currentRealm (with a leading underscore like I do within my book) is a field within the parent method. If it is not of the expected type, we throw an exception.

In line 10 we call the method which returns an array of permitted group names. If the
authentication fails, this method does not return any group name. Otherwise we call
commitUserAuthentication by passing in this array.

Within obtainPermittedGroups we need to check the user credentials and to determine the
permitted groups.

Ensure your GlassFish server is down and add this to your domain’s login.conf file:

alumniRealm {
 de.muellerbruehl.alumnirealm.LoginModule required;
};

Within the same folder, edit the domain.xml file too.
Here you need to add the authentication realm within the <security-service> tag.

...
 <security-service>
 <auth-realm classname="de.muellerbruehl.alumnirealm.AlumniRealm" 
 name="alumniRealm"></auth-realm>
 ...
 </security-service>
...

You may add this realm after booting your server at the admin console.

Edit your web.xml file to use the new realm.

 <realm-name>alumniRealm</realm-name>

Have fun and stay tuned!

(This article is a shortened excerpt of the chapter Authenticate of my book. JASPIC and the new security RI Soteria will be matter of an other chapter.)

 

 

 

Securing my WebSites

In my book about web development, I’m describing how to build applications with Java EE 7 and Java EE 8 (including some step by step tutorials by means of NetBeans). One application is a social network app called Alumni. This needs to be secured. I finally installed TLS on my web sites (including this blog), thus preparing alumni-web.de for the application described in my book (available soon).

Living book. Pausing soon.

In 2014 I started writing my book “Web Development with Java and JSF”. My intention was to write a book of apx. 200-250 pages. In my book I combined the theoretical background with a practical approach by building real applications. Can you build applications with JSF only? Nope. A JSF app runs within a servlet container which is part of Java EE. Java EE provides a lot of other features needed in a real application, e.g. persistence, security and much more. Thus, describing real applications is much more than JSF only.

In fact my book grew up and became a living book: Once purchased you are able to download any further update without additional fee. Today, my book reached 400 pages and I have prepared some more interesting topic which will be added soon.

Beside this book, I wrote a short book, “Java Lambdas and Parallel Streams”. In 2016 Apress asked me to publish both books. I agreed with the short one. But for the JSF book I wanted to add more content. This year, Apress asked again and I agreed, because the book reached a state which is ready to become a printed book. Usually, one month after signing the contract with Apress, the book needs to be off the market. Since I feel engaged with my existing readers, we changed this: I’m able to update my book one additional month after the milestone of “acceptance” is reached.

Apress started to promote my book [1]. Thus, I expect this milestone to be reached soon. For my existing readers, this does not denote the end of updates, but a pause (one moth after reaching this milestone). Until then, I’ll provide new chapters as update. Once the book is published by Apress, I’ll provide additional information to my existing readers.

Although I stopped promoting the self-published version, it is still available for readers who want to read about this matter soon. Apress started copy-editing my book (and this wont become part of the self-published version). This means, you’ll get a better quality with respect to the (American) English language, typos etc. And beside an electronic version, you may purchase a “real” book.

When they published my other book, Apress offered a discount of 60% for my existing readers. Maybe this offer is still valid for the JSF book…

Stay tuned!

 

[1] www.apress.com/us/book/9781484230299