Spring Security Certificate Authentication Authorization Example
In continuation of my earlier blog Container based Security and Spring Security, in this blog, I will demonstrate how you can achieve Certificates Authentication and Authorization in Spring Security. As with all my blogs, the sample code for this is @ Github.
As mentioned in Enabling CLIENT-CERT based authorization on Tomcat,
- You need to create keystore information
- You need to change the connector configuration in tomcat to work with SSL
- We dont need to configure MemoryRealm, because we use Spring Security for authentication
Continue and do the below steps,
- Go to spring-mvc-client3 folder in the sample codebase and run “mvn clean package -DskipTests” it will create a war file in target folder, copy the war file into tomcat webapps folder.
- Go to spring-mvc-client4 and repeat the maven command and copy the war file into tomcat webapps folder.
- Start the tomcat server by going to <tomcat installed folder>/bin/startup.bat
- Go to spring-mvc-client3 folder and run “mvn test” and notice all the tests are successful
To understand what is going open spring-mvc-client3/src/main/webapp/WEB-INF/applicationContext-security.xml, you will notice below configuration,
<!-- There is no security requirement to access the html resources like css, js etc and maybe loggedout.jsp page -->
<http pattern="/static/**" security="none"/>
<http pattern="/loggedout.jsp" security="none"/>
<http use-expressions="true">
<!-- Only supervisor can access secure1 webresources and all the resources under it and this resource can be accessed only if the request is https-->
<intercept-url pattern="/secure1/**" access="hasRole('supervisor')" requires-channel="https"/>
<!-- You have to be logged in to access secure folder and all resources under it -->
<intercept-url pattern="/secure/**" access="isAuthenticated()" requires-channel="https"/>
<!-- You have to be logged in to access secure folder and all resources under it -->
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="https"/>
<!-- Here is where you provide a regular expression to extract user identity from the certificate and pass it to a authentication provider, in this example,
there is a dummy authentication provider as below, in real example, the auth provider is something like LDAP -->
<x509 subject-principal-regex="CN=(.*?)," user-service-ref="accountService" />
</http>
<authentication-manager>
<authentication-provider>
<!-- Dummy anthentication provider -->
<user-service id="accountService">
<user name="client1" password="" authorities="supervisor" />
<user name="client2" password="" authorities="user" />
</user-service>
</authentication-provider>
</authentication-manager>
Open the JUnit test @ spring-mvc-client3/src/test/java/com/goSmarter/springsecurity/SecureHttpClient1Test.java and see based on the above configuration, I have 2 positive testcases and 1 negative testcase. If you notice testSecurePage, user “client1″ can access “secure1″ folder because he is a “supervisor”, it is returning http OK(200). If you notice testSecurePageNegativeCase, user “client2″ cannot access “secure1″ folder because he is a “user”, it is giving forbidden(403) http code.
I hope this blog helped you.
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)





