Reputation: 135
I am developing a simple spring security app that has 3 user roles(emp,admin,man). I read user data by datasource and also i have my own access-denied page for the situation that any user wants to access to forbidden pages. before I used to define my user information(username, password, roles) on my java class DemoSecurityConfig in the method protected void configure ()
and spring security could notice what page each user can access but the problem is that since I am reading the information from the database all my users directed to the access denied page which means spring security roles don't work or it can't read the given role
DemoSecurityConfig class
@Configuration
@EnableWebSecurity
@ComponentScan(basePackages = "com")
public class DemoSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource securityDataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//use jdbc
auth.jdbcAuthentication().dataSource(securityDataSource);
}
//configure of web patch in application login logout
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/").hasAnyRole("emp")
.antMatchers("/leaders/**").hasAnyRole("man")
.antMatchers("/systems/**").hasAnyRole("admin")
.and().formLogin().loginPage("/showMyLoginPage")
.loginProcessingUrl("/authenticateTheUser")
.permitAll().and().logout().permitAll().and().exceptionHandling().accessDeniedPage("/access-denied");
}
}
DemoAppConfig
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com")
@PropertySource("classpath:persistence-mysql.properties")
public class DemoAppConfig {
//define a bean for view resolver
@Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver viewResolver=new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
//reading properties file
//set yp varible for holding a properties
@Autowired
private Environment env;
private Logger logger=Logger.getLogger(getClass().getName());
//define a bean for data source
@Bean
public DataSource securityDataSource(){
//create data connection
ComboPooledDataSource securityDataSource
=new ComboPooledDataSource();
//set up jdbc driver class
try {
securityDataSource.setDriverClass(env.getProperty("jdbc.driver"));
} catch (PropertyVetoException exc) {
throw new RuntimeException(exc);
}
//log the connection for make sure
logger.info(">> jdbc.url=" +env.getProperty("jdbc.url"));
logger.info(">> jdbc.user=" +env.getProperty("jdbc.user"));
//set up database connection properties
securityDataSource.setJdbcUrl(env.getProperty("jdbc.url"));
securityDataSource.setUser(env.getProperty("jdbc.user"));
securityDataSource.setPassword(env.getProperty("jdbc.password"));
//set yp connection props
securityDataSource.setInitialPoolSize(getIntProperty("connection.pool.initialPoolSize"));
securityDataSource.setMinPoolSize(getIntProperty("connection.pool.minPoolSize"));
securityDataSource.setMaxPoolSize(getIntProperty("connection.pool.maxPoolSize"));
securityDataSource.setMaxIdleTime(getIntProperty("connection.pool.maxIdleTime"));
return securityDataSource;
}
//need a helper class
//read env property and convert to int
private int getIntProperty(String proName){
String proVal=env.getProperty(proName);
int intPropVal=Integer.parseInt(proVal);
return intPropVal;
}
}
home.jsp
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>this is a main page</h1>
<!-- add link to point to leaders -->
<security:authorize access="hasRole('admin')">
<p>
<a href="${pageContext.request.contextPath}/systems">IT meeting</a>
(only for admins)
</p>
<br/>
<p>
</security:authorize>
<security:authorize access="hasRole('man')">
<a href="${pageContext.request.contextPath}/leaders">leaders meeting</a>
(only for admins)
</p>
<br/>
</security:authorize>
<form:form action="${pageContext.request.contextPath}/logout" method="post">
<input type="submit" value="Logout">
<hr>
<-- display user -->
User: <security:authentication property="principal.username"/>
<br><br>
roles <security:authentication property="principal.authorities"/>
</hr>
</form:form>
</body>
</html>
Upvotes: 0
Views: 1883
Reputation: 90447
From the hasAnyRole()
javadoc :
Shortcut for specifying URLs require any of a number of roles. If you do not want to have "ROLE_" automatically inserted see hasAnyAuthority(String...)
So hasAnyRole("emp")
expects the user has the role ROLE_emp
but the user has the role emp
now .
Either update all user authorities in database to be prefixed with ROLE_
such as ROLE_emp
and ROLE_admin
or change to use hasAnyAuthority()
which will not add the ROLE_
prefix :
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").hasAnyAuthority("emp")
.antMatchers("/leaders/**").hasAnyAuthority("man")
.antMatchers("/systems/**").hasAnyAuthority("admin")
......
}
Upvotes: 2