March 30, 2011

Spring Security by example: securing web resources

This is a part of a simple Spring Security tutorial:

1. Set up and form authentication
2. User in the backend (getting logged user, authentication, testing)
3. Securing web resources
4. Securing methods
5. OpenID (login via gmail)
6. OAuth2 (login via Facebook)
7. Writing on Facebook wall with Spring Social

Securing web resources means making sure that only users with granted authority will be able to visit given URL.

Let's say we have a page “protected.html” that should be accessed only by our admin. First thing we have to do, is to define which URLs are protected and which are accessible for anonymous user. We do that by adding intercept-url tags and a decision manager to the http tag:
<http access-decision-manager-ref="accessDecisionManager">

    <!-- intercepted urls -->
    <intercept-url pattern="/j_spring_security_logout" access="IS_AUTHENTICATED_FULLY, IS_AUTHENTICATED_REMEMBERED" requires-channel="https"/>
    <intercept-url pattern="/j_spring_security_check" access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="https"/>
    <intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="https"/>
    <intercept-url pattern="/protected.html" access="ROLE_ADMIN" requires-channel="https"/>
    <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="http"/>


The important part is the “access” attribute. It's value may be any set of strings delimited by coma, as long as those strings have any sense to our decision manager.
<beans:bean id="accessDecisionManager" class="">
        <beans:property name="decisionVoters">
                <beans:bean class="">
                    <beans:property name="rolePrefix" value="ROLE_"/>
                <beans:bean class=""/>
Out of the box we have three different decision managers. Each fires up a set of voters (a voter is responsible for either granting access, denying access or abstaining from voting) and gathers up the outcomes.

AffirmativeBased decision manager will grant access if any voter said OK.
UnanimousBased decision manager will grant access ONLY if all voters said OK.
ConsensusBased decision manager will let the majority decide. It actually counts each vote. You can configure it to behave as you wish in case of a tie.

Here we are using  AffirmativeBased decision manager voter with two voters: RoleVoter and AuthenticatedVoter.

The former will check whether any string in “access” atribute starts with “ROLE_”  (you can change that if you wish) and for each of them, will check whether current user has a corresponding granted authority. In your case, for “/protected.html” URL, it means that AuthenticationUserDetails has to have a GrantedAuthorityImpl with string ROLE_ADMIN.

AuthenticatedVoter on the other hand, will search for strings IS_AUTHENTICATED_FULLY, IS_AUTHENTICATED_ANONYMOUSLY, IS_AUTHENTICATED_REMEMBERED (cookie) and vote for yes in corresponding cases. In ours, that means, only users logged in can access logout (/j_spring_security_logout), and only anonymous users can access anything else. The last intercepted URL ("/**") is equivalent to “everything” and ordering is important just like with CISCO ACLs.

This allows us to build quite complicated patterns.

As with many other security systems, a user that didn't login, is considered anonymous. This is done by AnonymousAuthenticationFilter, which is by default in our chain of filters.

Next: Securing methods

No comments:

Post a Comment