I'm working in a web application using spring mvc 4 (version: 4.0.9.RELEASE) and spring security 3 (version: 3.2.5.RELEASE), my problem is that i can't restrict access to specific view (.html page) inside a folder.
I have three (3) modules in my web application: Roles, Permissions, Users. Each module have CRUD operations (insert, create, read, delete). I have created twelve (12) permissions in forms of roles in my spring secuirty configuration, each permission would be in charge of a CRUD operation, i would have a permission to create users another one to delete roles and so on until i have 12 permissions.
I said that i created those permissions as roles is because in my web application i have a create role requeriment and in this requeriment i can create a new role and this new role can have permissions mixed from modules, i mean i can create a role that have a create user permission and also delete a role permission.
Beacuse of this i can´t have harcoded the access to the modules using roles in my spring security configuration , but since is not a requeriment to create new permissions i used the permissions to be hardcoded instead of the roles in my spring security configuration.
Even if i use this Spring EL expressions "hasRole", in my bussines logic the string i pass to that expression is a name of a permission that i have stored in my data base.
I have 3 folders: Roles, Permissions, Users; and each folder contains a page for each crud operation like this:
---Roles
--addRole.html
--deleteRole.html
--readRole.html
--insertRole.html
---Users (same level as Role)
--.... the same as role but with users
---Permissions (same level as Role)
--...the same as role but with permission
My problem is that i want to create my spring secuirty configuration to restrict access per page and not per folder, i would like to need to have a specific permission to access a page like this
.antMatchers("/addRole/**").access("hasRole('PERM_ADD_ROLE')")
.antMatchers("/deleteRole/**").access("hasRole('PERM_DELETE_ROLE')")
.antMatchers("/readRole/**").access("hasRole('PERM_READ_ROLE')")
.antMatchers("/insertRole/**").access("hasRole('PERM_INSERT_ROLE')"
.antMatchers("/addUser/**").access("hasRole('PERM_ADD_USER')")
.antMatchers("/deleteUser/**").access("hasRole('PERM_DELETE_USER')")
But when i do this if i log-in with a user that have PERM_ADD_ROLE this user have access to all the ROLE pages ( deleteRole, readRole an insertROle) and this shouldn't happen, the user should have only access to the addRole page since his permission is "PERM_ADD_ROLE", but since the other pages i mention are in the same folder Roles i believe thats why he access them but this shouldn't happen.
My project in spring mvc is configured using java config and no XMLs, i have my application configured with classes and not XML
Here is my spring security class configuration.
@Configuration
@EnableWebMvcSecurity
public class SecurityConfign extends WebSecurityConfigurerAdapter {
@Autowired
private AutProvider aut;
@Override
protected void configure( HttpSecurity http ) throws Exception
{
http
.authenticationProvider(aut)
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.antMatchers("/css/**").permitAll()
.antMatchers("/js/**").permitAll()
.antMatchers("/img/**").permitAll()
.antMatchers("/sound/**").permitAll()
.antMatchers("/fonts/**").permitAll()
.antMatchers("/ajax/**").permitAll()
.antMatchers("/php/**").permitAll()
.antMatchers("/xml/**").permitAll()
.antMatchers("/addRole/**").access("hasRole('PERM_ADD_ROLE')")
.antMatchers("/deleteRole/**").access("hasRole('PERM_DELETE_ROLE')")
.antMatchers("/readRole/**").access("hasRole('PERM_READ_ROLE')")
.antMatchers("/insertRole/**").access("hasRole('PERM_INSERT_ROLE')"
.antMatchers("/addUser/**").access("hasRole('PERM_ADD_USER')")
.antMatchers("/deleteUser/**").access("hasRole('PERM_DELETE_USER')")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login/login")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.csrf().disable();
}
}
And here is my AuthenticationProvider class
@Component
public class AutProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
String name = null;
String password = null;
Authentication auth = null;
try {
name = authentication.getName();
password = authentication.getCredentials().toString();
if (name.equals("admin@admin.com") && password.equals("password")) {
List<GrantedAuthority> grantedAuths = new ArrayList<>();
grantedAuths.add(new SimpleGrantedAuthority("PERM_ADD_ROLE"));
grantedAuths.add(new SimpleGrantedAuthority("PERM_ADD_USER"));
auth = new UsernamePasswordAuthenticationToken(name, password, grantedAuths);
}
} catch (AuthenticationException e) {
e.printStackTrace();
throw e;
}
return auth;
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
and here is some of my controllers as and example the Role COntroller
@Controller
@RequestMapping("/roles/")
public class RoleController {
@RequestMapping(value = "readRole", method = RequestMethod.GET)
public String readArole(Model model) {
return "/roles/readRole";
}
}
In resume if i give a specifc permission to a user like PERM_ADD_ROLE with this permission the user have access to all the pages in the Roles folder and this shouldn't happen.