In this tutorial we’ll focus on Spring Security Expressions, and of course on practical examples with these expressions.
Before looking at more complex implementations (such as ACL), it’s important to have a solid grasp on security expressions as they can be quite flexible and powerful if used correctly.
This article is an extension of Spring Security Expressions hasRole Example .
2. Maven DependenciesIn order to use Spring Security, you need to include the following section in your pom.xml file:
<dependencies><dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.1.1.RELEASE</version>
</dependency>
</dependencies>
Latest version can be found here .
And a quick note this dependencyonly covers Spring Security; don’t forget to add s pring-core and spring-context for a full web application.
3. ConfigurationFirst, let’s take a look at a Java configuration.
We’ll extend WebSecurityConfigurerAdapter so that we have the option to hook into any of the extension points that base class offers:
@Configuration@EnableAutoConfiguration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityWithoutCsrfConfig extends WebSecurityConfigurerAdapter {
...
}
We can of course do an XML configuration as well:
<?xml version="1.0" encoding="UTF-8"?><beans:beans ...>
<global-method-security pre-post-annotations="enabled"/>
</beans:beans> 4. WebSecurity Expressions
Now, let’s start looking at the security expressions:
hasRole, hasAnyRole hasAuthority,hasAnyAuthority permitAll, denyAll isAnonymous, isRememberMe, isAuthenticated, isFullyAuthenticated principal, authentication hasPermissionAnd let’s now go over each of these in detail.
4.1. hasRole, hasAnyRoleThese expressions are responsible for defining the access control or authorization to specific URLs or methods in your application.
Let’s look at the example:
@Overrideprotected void configure(final HttpSecurity http) throws Exception {
...
.antMatchers("/auth/admin/*").hasRole("ADMIN")
.antMatchers("/auth/*").hasAnyRole("ADMIN","USER")
...
}
In this example we specify access to all links starting with /auth/ restricted to users that arelogged in with role USER or role ADMIN. Moreover,to access links starting with /auth/admin/ we need to have ADMIN role in the system.
The same configuration might be achieved in XML file, by writing:
<http><intercept-url pattern="/auth/admin/*" access="hasRole('ADMIN')"/>
<intercept-url pattern="/auth/*" access="hasAnyRole('ADMIN','USER')"/>
</http> 4.2. hasAuthority, hasAnyAuthority
Roles and authorities are similarin Spring.
The main difference is that, roles have special semantics starting with Spring Security 4, the ‘ ROLE_ ‘ prefix is automatically added (if it’s not already there) by any role related method.
So hasAuthority(‘ROLE_ADMIN’) is similar to hasRole(‘ADMIN’) because the ‘ ROLE_ ‘ prefix gets added automatically.
But the good thing about using authorities is that we don’t have to use the ROLE_ prefix at all.
Here’s a quick example where we’re defining users with specific authorities:
@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user1").password("user1Pass")
.authorities("USER")
.and().withUser("admin").password("adminPass")
.authorities("ADMIN");
}
We can then of course use these authorities expressions:
@Overrideprotected void configure(final HttpSecurity http) throws Exception {
...
.antMatchers("/auth/admin/*").hasAuthority("ADMIN")
.antMatchers("/auth/*").hasAnyAuthority("ADMIN", "USER")
...
}
As we can see we’re not mentioning roles at all here.
Finally we can of course achieve the same functionality using XML configuration as well:
<authentication-manager><authentication-provider>
<user-service>
<user name="user1" password="user1Pass" authorities="ROLE_USER"/>
<user name="admin" password="adminPass" authorities="ROLE_ADMIN"/>
</user-service>
</authentication-provider>
</authentication-manager>
And:
<http><intercept-url pattern="/auth/admin/*" access="hasAuthority('ADMIN')"/>
<intercept-url pattern="/auth/*" access="hasAnyAuthority('ADMIN','USER')"/>
</http> 4.3. permitAll, denyAll
Those two annotations are also quite straightforward. We either may permit access to some URL in our service or we may deny access.
Let’s have a look at the example:
....antMatchers("/*").permitAll()
...
With this config, we will authorize all users (both anonymous and logged in) to access the page starting with ‘/’ (for example, our homepage).
We can also deny access to our entire URL space:
....antMatchers("/*").denyAll()
...
And again, the same config can be done with an XML config as well:
<http auto-config="true" use-expressions="true"><intercept-url access="permitAll" pattern="/*" /> <!-- Choose only one -->
<intercept-url access="denyAll" pattern="/*" /> <!-- Choose only one -->
</http> 4.4. isAnonymous, isRememberMe, isAuthenticated, isFullyAuthenticated
In this subsection we focus on expressions related to login status of the user. Let’s start with user that didn’t log in to our page. By specifying following in Java config, we enable all unauthorized users to access our main page:
....antMatchers("/*").anonymous()
...
The same in XML config:
<http><intercept-url pattern="/*" access="isAnonymous()"/>
</http>
If we want to secure the website that everybody who usesit will be required to login, we need to use isAuthenticated() method:
....antMatchers("/*").authenticated()
...
orXML version:
<http><intercept-url pattern="/*" access="isAuthenticated()"/>
</http> Moreover, we have two additional expressions, isRememberMe() and isFullyAuthenticated() . Through the use of cookies, Spring enables remember-me capabilities so there is noneed to log into the system each time. You can read