Spring Security customising method level authorization

If you’ve used Spring Security before you’ve probably used @Secured or @PreAuthorize annotations to enable method level security. These annotations are specifically useful for preventing your web applications being attacked by malicious users. Method level security makes sure that only authorized users can execute the specific method.

Depending upon the specific problem you can either use @Secured

 @Secured({ "ROLE_DBA","ROLE_ADMIN","ROLE_SUPER_ADMIN"})
void updateUser(){

//.....

}

Or you can use @PreAuthorize

@PreAuthorize("hasRole('ADMIN', 'ROLE_DBA', 'ROLE_SUPER_ADMIN')")
void updateUser(User user){

}

However, the limitation with the above annotations is that rely on GrantedAuthorities of the in session user. In other words, you are limited to the just the roles of the user to control the access to a specific method.

What about when you want to use another attribute, lets says a STATUS determined by an external service?

Or perhaps you have there is a reasonable amount to logic involved before deciding a particular user has access to a specific controller level method of your Spring app?

Under such circumstances you can leverage the ability to call custom methods through the @PreAuthorize annotation.  You can create a custom AccessManager spring managed bean (or something else suitably named for your app)

 


@Component("accessManager")
public class AccessManager{ 

	@Autowired
	MyThirdPartyService myThirdPartyService;

	public boolean hasAccess(Authentication authentication, String... statusesNotAllowed) {
	//Complex logic can be performed here.
	//1. Access user's data with the authentication object
	//2. Access third party service to access data not available (or shouldn't be part of) in the session
	//3. statusesNotAllowed an example paramter, can have more or less
	}
}

 

The AccessManager.hasAccess() method can be called in the @PreAuthorize annotation anywhere in your application. Only when AccessManager.hasAccess method returns true with the parameters specified in the annotation, the updateUser method would get executed.


@PreAuthorize("@accessManager.hasAccess(authentication, {'CANCELLED', 'BLOCKED', 'TERMINATED'})")
public String updateUser(User user){
	....
}

 

Disable SSL v3 on JBoss AS 7.1.1

SSLv3 is vulnerable to POODLE attacks. If you’re running your web application on JBoss AS 7.1, you need to disable SSLv3 in order to protect your web application from POODLE attacks. JBoss AS 7.1 does support more recent versions of TLS but it is still subject to a downgrade attack i.e. the attacker tricks the browser into connecting with SSL v3.

How to test if your JBoss Server still uses SSL v3

Before attempting to disable SSL v3, you should make sure that your application can indeed be accessed via SSL v3. In order to do that:

  1. Open Internet Explorer
  2. On the browser, under options, turn off TLS 1.2, TLS 1.1, TLS 1.0 and SSL 2.0 and only allow SSL v3 (In Internet Explorer this is under Internet Options & Advanced tab)
  3. Try to access the web page of your app deployed on JBoss AS 7.1 server.
    • If you can successfully navigate to the page that means SSL v3 is enabled.
    • If you cannot navigate to the page that means SSL v3 is disbaled. This means your web application is already protected against POODLE and you don’t need to do anything.
  4. Now turn TLS back on, try to access the web page again, you should be able to access the site.
Configure IE to only use SSL v3

Configure IE to only use SSL v3

How to disable SSL v3

To disable SSLv3 in JBoss you need to make sure SSLv3 is not listed in the list of protocols in standalone.xml on your JBoss server.

  1. Open standalone.xml file
    • It is located in the configuration folder of your JBoss App server directory.
  2. Modify https connector config.
    • Change the value of protocols attribute to TLSv1, TLSv1.1, TLSv1,2.
    • Notice below in the original config – protocol list only contains TLSv1 and protocol is changed to protocols in the modified xml.

Code snippet from original configuration file.

<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
        <ssl name="foo-ssl" key-alias="foo" password="secret" certificate-key-file="your\file\path\to\the\certificate" protocol="TLSv1"/>
</connector>

Modified code snippet.

<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
        <ssl name="foo-ssl" key-alias="foo" password="secret" certificate-key-file="your\file\path\to\the\certificate" protocol="TLSv1,TLSv1.1,TLSv1.2"/>
</connector>

Please note that if you’re running Java 6(JDK or JRE), you can only run TLS v1.0. TLSv1.1 and TLSv1.2 require Java 7 (minimum) to be running on your server.