While working on a new project I needed to add good old authentication and authorization for a RESTful web service. There are many popular frameworks out there for doing this but with the mindset that less is more I wanted to see if I could do it without adding yet another framework. I've been very happy with Java EE 6 and how they really have come a long way on simplicity so I put it to the test in the requirement. Below is all I had to do to protect my resources.
1. Configure Glassfish to provide a security realm. I used a jdbcRealm that pointed to my database. The 2 tips I have for this is if your db schema doesn't have the structure the container wants simply create a view. The second is make sure your JAAS Context name is "jdbcRealm" this is a "special" identifier and it doesn't work if you pick your own.
2. Configure the web.xml to specify what resources you want protected. It ended up looking like this:
3. Inject SessionContext where I needed to get Principal information for user-level authorization. It ended up being a simple method in my base resource class I call when I need to know which username was authenticated:
I was very happy to be able to implement this common use case with Java EE 6 and not have to pull in yet another framework!
1. Configure Glassfish to provide a security realm. I used a jdbcRealm that pointed to my database. The 2 tips I have for this is if your db schema doesn't have the structure the container wants simply create a view. The second is make sure your JAAS Context name is "jdbcRealm" this is a "special" identifier and it doesn't work if you pick your own.
2. Configure the web.xml to specify what resources you want protected. It ended up looking like this:
<security-constraint>
<display-name>user authentication</display-name>
<web-resource-collection>
<web-resource-name>Requiring authorization resources</web-resource-name>
<description></description>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>HEAD</http-method>
<http-method>PUT</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<auth-constraint>
<description>Have to be a USER</description>
<role-name>Consumer</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>login</realm-name>
</login-config>
<security-role>
<description/>
<role-name>Consumer</role-name>
</security-role>
3. Inject SessionContext where I needed to get Principal information for user-level authorization. It ended up being a simple method in my base resource class I call when I need to know which username was authenticated:
@Resource
private SessionContext sessionContext;
protected String getCallerUsername() {
Principal principle = sessionContext.getCallerPrincipal();
return principle.getName();
}
I was very happy to be able to implement this common use case with Java EE 6 and not have to pull in yet another framework!