Monday, June 9, 2008

Using Spring Security to Secure a Webapp

I had to go to a few different places to get all this working, but I have simple security on a webapp that secures the URLs and a method on a DAO interface. Besides securing the delete method in the DAO interface, the link is also hidden from non-admin users. I have this working with JDBC authentication and also with static users defined in the XML (which are commented out, but still in the XML configuration).

Basically you just need to define a security filter, configure Spring Security in an XML file, secure methods either with pointcuts in the XML or with annotations.


Secure DAO Method
Either secure with an annotation-based config, as in the example posted.

<security:global-method-security secured-annotations="enabled" />

/**
  * Deletes person.
  */
@Secured ({"ROLE_ADMIN"})
public void delete(Person person);

Or as a pointcut in the XML configuration.

<security:global-method-security>
     <!-- Any delete method in a class ending in 'Dao' in the 'org.springbyexample.orm.hibernate3.annotation.dao' package. -->
     <security:protect-pointcut
         expression="execution(* org.springbyexample.orm.hibernate3.annotation.dao.*Dao.delete(..))"
        access="ROLE_ADMIN"/>
</security:global-method-security>

In Spring Security Config
<security:authentication-provider>
     <security:jdbc-user-service data-source-ref="dataSource" />
</security:authentication-provider>

SQL Script
Script works for HSQLDB and based on Spring Security Script. The ACL tables aren't defined because they aren't used at all in this example.

SET IGNORECASE TRUE;

CREATE TABLE users (
     username VARCHAR(50) NOT NULL PRIMARY KEY,
     password VARCHAR(50) NOT NULL,
     enabled BIT NOT NULL
);

CREATE TABLE authorities (
     username VARCHAR(50) NOT NULL,
     authority VARCHAR(50) NOT NULL
);
CREATE UNIQUE INDEX ix_auth_username ON authorities (username, authority);

ALTER TABLE authorities ADD CONSTRAINT fk_authorities_users foreign key (username) REFERENCES users(username);

INSERT INTO users VALUES ('david', 'newyork', true);
INSERT INTO users VALUES ('alex', 'newjersey', true);
INSERT INTO users VALUES ('tim', 'illinois', true);

INSERT INTO authorities VALUES ('david', 'ROLE_USER');
INSERT INTO authorities VALUES ('david', 'ROLE_ADMIN');
INSERT INTO authorities VALUES ('alex', 'ROLE_USER');
INSERT INTO authorities VALUES ('tim', 'ROLE_USER');

No comments: