Spring 安全性与给定角色不匹配
Posted
技术标签:
【中文标题】Spring 安全性与给定角色不匹配【英文标题】:Spring security doesn't match a given role 【发布时间】:2020-06-14 17:10:20 【问题描述】:我正在开发一个简单的 spring 安全应用程序,它有 3 个用户角色(emp、admin、man)。我通过数据源读取用户数据,并且对于任何用户想要访问禁止页面的情况,我都有自己的拒绝访问页面。在我使用方法protected void configure ()
在我的 java 类 DemoSecurityConfig 上定义我的用户信息(用户名、密码、角色)之前,spring security 可以注意到每个用户可以访问的页面,但问题是因为我正在从数据库我的所有用户都被定向到拒绝访问页面,这意味着 spring 安全角色不起作用或无法读取给定的角色
DemoSecurityConfig 类
@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>
【问题讨论】:
【参考方案1】:来自hasAnyRole()
javadoc:
指定 URL 的快捷方式需要多个角色中的任意一个。如果你 不想让“ROLE_”自动插入见 hasAnyAuthority(String...)
所以hasAnyRole("emp")
期望用户拥有ROLE_emp
角色,但用户现在拥有emp
角色。
要么将数据库中的所有用户权限更新为前缀为 ROLE_
,例如 ROLE_emp
和 ROLE_admin
,要么更改为使用不会添加 ROLE_
前缀的 hasAnyAuthority()
:
protected void configure(HttpSecurity http) throws Exception
http.authorizeRequests()
.antMatchers("/").hasAnyAuthority("emp")
.antMatchers("/leaders/**").hasAnyAuthority("man")
.antMatchers("/systems/**").hasAnyAuthority("admin")
......
【讨论】:
以上是关于Spring 安全性与给定角色不匹配的主要内容,如果未能解决你的问题,请参考以下文章
使用 Spring Boot 的角色层次结构和 OAuth2 安全性
如何为 Spring Security 创建类型安全的用户角色?
Spring-boot 安全性不会尊重具有自定义 AuthenticationProvider 的角色 [重复]