In order to add some extra and reliable means of security in Grails application we mostly prefer to use 2FA either using Yubikey or some other way. In this context Grails Spring Security Filter not only provides us an easy and flexible methods to do so rather it also maintains a proper flow of authentication in our application by mean of chain of filters. We can simply add an extra filter in chain or override existing one to get our required functionality. In this post we will go through a proper procedure to see how can we enable 2FA using Yubikey by Spring Security filter and will see how can we integrate it with our Grails application.
Problem with Single Factor Authentication (SFA)
Many organizations protect local and remote logins with a simple username and password. Entering these two pieces of information grants access to company sensitive information. Passwords are notoriously insecure and many users choose weak passwords which can be easily guessed or cracked. Malicious viruses and spyware can capture passwords and send them over the network to attackers.
Furthermore, it’s impossible to tell who has access to your users’ accounts, or even if anyone is accessing them illicitly. Clearly passwords are not enough for protecting important logins.
Use Two-Factor Authentication
The most practical way to strengthen authentication is to require a second factor after the username/password stage. Two-factor authentication is a strong authentication method where the user provides two types of identification. Two-factor authentication combine something you know (a PIN or password) with something you have (a physical device like a Yubikey). The Yubikey will work with any computer that can support a USB keyboard, and can uniquely identify itself with the one-time password it generates making it excellent device for two-factor authentication.
Two-factor authentication simply adds a second credential in addition to the username (and password) on which to authenticate. For example, in addition to a username to couple with a password, you may require the user to enter yubikey One Time Password, SMS code ,domain name etc.
Grails Spring Security Filter Chain
Spring Security maintains a filter chain internally where each of the filters has a particular responsibility and filters are added or removed from the configuration depending on which services are required. The ordering of the filters is important as there are dependencies between them. If you have been using namespace configuration, then the filters are automatically configured for you and you don't have to define any Spring beans explicitly but here may be times when you want full control over the security filter chain, either because you are using features which aren't supported in the namespace, or you are using your own customized versions of classes.
When a user tries to access a protected resource and Spring Security determines they aren't authenticated, an implementation of AuthenticationEntryPoint is called. The AuthenticationEntryPoint is basically what starts the authentication process. The most common implementation is LoginUrlAuthenticationEntryPoint which simply redirects the user to a login page so they can enter credentials.
When a user enters credentials the form submits to the action specified. Each request gets passed down a chain of security filters which look at the request URI, and if a filter matches what it is looking for to that action value, it will know to execute on that request. The default filter that handles logins is the UsernamePasswordAuthenticationFilter.
public UsernamePasswordAuthenticationFilter() {
super(“/j_spring_security_check”);
}
The value “/j_spring_security_check” is what this filter is looking for in the URI of incoming requests. When the filter sees this value in the URI of a request, it will try to authenticate with the information in the request, otherwise it will pass it off to the next filter in the chain.
By default Spring Security filter chain does work for single authentication i.e; UserName and Password. In some application where security is more concern we need to add some extra level of security. To make this multi factor authentication possible through Spring Security we need to either override its default filter behaviour or write custom filter and register it in spring security filter chain.
Two-factor Authentication using Yubikey through Spring Security
In order to make 2FA possible through Spring Security using Yubikey we have to follow these steps:-
Add extra input field on Login page to accept Yubikey OneTimePassword entered using Yubikey. The name of input field should follow some naming convention as default behaviour of Spring Security authentication accept these parameters with ” j_” prefix so input field can be defined in this way:
<input type="text" id="yubikeyOneTimePassword" class="inp" name=”j_oneTimePassword" value="">
We have to take this input field value while submitting the form from Login page.
We should have a custom authentication filter which can use this Yubikey OneTimePassword value along with username and password fields.
Spring Security already has a UserNamePasswordAuthentication filter, we have to add extra layer of filter along with existing filters so that it can use Yubikey OneTimePassword parameter’s value and workable for Two-factor authentication.
In order to do that custom authentication filter must extends current implementation of UserNamePasswordAuthentication filter.
Override the existing functionality of attemptAuthentication method of UserNamePasswordAuthentication filter and add functionality for yubikey authentication. After successful authentication call attemptAuthentication method of parent class.
In order to save the Yubikey OneTimePassword value so that it can be authenticated and used later on we need to get it from HttpServletRequest. It can be better defined in a separate function.
protected String obtainYubiKeyOneTimePassword(HttpServletRequest request){
return request.getParameter("j_oneTimePassword");
}
We have to ensure that the parameter name “j_oneTimePassword” should be same as Login page input field name.
By following all these preceding steps we will be able to get username,password and Yubikey OneTimePassword from Login page. Username and password are authenticated through database but Yubikey OneTimePassword can only be authenticated by either Yubico vaildation server or make your own authentication server and integrate it with yubico server.
Yubikey OneTimePassword validation through Yubico validation server
In order to authenticate Yubikey OneTimePassword we can use any one of Yubico Client which suits best for our application. Let’s take an example of Java Yubico Client.
We need to create a jar file from this open source code so that we can use it in our application .
Add jar in library of application and import the classes where appropriate .
We can get a particular api-key to use Yubico-client applications Yubico-API
There are multiple functions exists in this java-yubico-client api which we can use to verify our entered Yubikey OneTimePassword. Let’s take an example of them:
String yubiKeyPublicId ;
YubicoClient client = YubicoClient.getClient(client-api-key);
YubicoResponse responseOTP =null
if (isValidOTPFormat(yubiKeyOTP))
responseOTP = client.verify(yubiKeyOTP);
if (responseOTP.getStatus() == YubicoResponseStatus.OK) {
yubiKeyPublicId = YubicoClient.getPublicId(yubiKeyOTP);
}
Complete description of Yubikey usage and its OneTimePassword parts details is available on Yubikey Details.
Add Custom Filter in Resource.groovy
Last thing that we need to do in order to use custom filter working in spring security is to add path of custom filter in Resource.groovy file. This can be done as follow:
authenticationProcessingFilter(YubiKeyAuthenticationFilter) {
authenticationManager = ref("authenticationManager")
authenticationSuccessHandler = ref('authenticationSuccessHandler')
authenticationFailureHandler = ref('authenticationFailureHandler')
}
Conclusion
Password managers like KeePass, LastPass, and 1Password are essential tools for storing the millions of unique and long passwords we have to generate each time. However, if you really want to secure your logins, a second layer of authentication will help. Two Factor Authentication with Yubikey is an affordable and easy to use option to further secure your sensitive data. The Yubikey is an unique USB device which can works with all devices and platforms without some specific driver or client software needs. Furthermore the Yubico server which also provides Yubikeys adds an extra layer of ease in authenticating and managing OneTimePasswords. As a conclusion we can say that Grails Spring Security Filter is a powerful weapon to tackle 2FA in Grails application in either way.
Summary
In this article we had explained the problem of single authentication method and how 2FA can be used with our applications to make them more secure. We had gone through step-by-step procedure to make 2FA possible with Yubikey. We also explained the multiple ways which we can be adoptable for Yubikey OneTimePassword authentication. In case of any further queries or questions please feel free to ask.
The source code for YubikeyAuthentication plugin is available on Github can be downloaded from there. This is the first working version and we hope to improve this in next versions.
Comments