Spring 安全性中的 @PreAuthorize 注释不起作用。可能配置错误 .xml 文件
@PreAuthorize annotation in Spring Security doesn't work. Might be misconfigured .xml file
我正在使用 Spring 安全性(Spring 启动应用程序)和 AngularJS,并且我正在尝试 allow/deny 访问基于用户授予的特定映射当局。
User.java
public class User implements UserDetails {
...
private String username;
private String password;
private boolean enabled;
private List<GrantedAuthority> grantedAuthorities;
public User(...) {...}
private class Permission implements GrantedAuthority {
String permission;
public Permission(String permission) {
this.permission = permission;
}
@Override
public String getAuthority() {
return permission;
}
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return grantedAuthorities;
}
...
}
此外,我有自己的 UserDetailsService
实现(方法 loadUserByUsername(String username)
),它使用数据库中的数据填充用户数据。
前面提到的映射是:
@RequestMapping("yes")
public void doesHaveAuthority() {yes();}
@PreAuthorize("hasAuthority('10001')")
private void yes() {}
@RequestMapping("no")
public void doesntHaveAuthority() {no();}
@PreAuthorize("hasAuthority('00000')")
private void no() {}
用户确实有权限“10001”,但没有权限“00000”,应该允许访问 /yes
,但不允许访问 /no
。不幸的是,两条路径都是允许的。
我有 spring-security-config
作为提到的 Maven 依赖项 here。
我的WEB-INF/web.xml
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/security.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
和WEB-INF/security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<context:component-scan base-package="com.mycompany.project" />
<global-method-security pre-post-annotations="enabled" />
</beans:beans>
所以,总结一下:UserDetailsService 实现有效(我可以使用用户凭据登录,记录器打印授予的权限,所以我知道它们在那里),但用户可以访问两者 yes
和 /no
路径实际上 he/she 不应该能够访问 /no
因为 he/she 没有权限(许可)“00000”.
也许我的 xml 配置不正确或根本没有被读取。
感谢您的宝贵时间
更新 正如 M. Deinum 在评论中所说 Spring 引导忽略 web.xml 和 security.xml 文件。解决方案是修改扩展 WebSecurityConfigurerAdapter
的 SecurityConfiguration
并添加具有相应权限的相应 antMatchers。
示例:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().and()
.authorizeRequests()
.antMatchers("/login.html", "/index.html", "/").permitAll()
.antMatchers("/yes").hasAuthority("10001")
.antMatchers("/no").hasAuthority("00000")
.anyRequest()
.authenticated().and()
.addFilterAfter(new CSRFHeaderFilter(), CsrfFilter.class)
.csrf().csrfTokenRepository(csrfTokenRepository());
}
用户"We are Borg"要求我post解决方案作为答案所以这里是:
基本上,因为我的应用程序是 Spring 引导应用程序,所以它被忽略了(忽略了我的 .xml 配置文件)。解决方案非常简单:扩展 WebSecurityConfigurerAdapter
并覆盖 configure(HttpSecurity)
方法。覆盖它时,请确保用户具有访问路径(antMatchers)的权限 and/or 权限。它应该看起来像这样:
SecurityConfiguration.java
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().and()
.authorizeRequests()
.antMatchers("/login.html", "/index.html", "/").permitAll()
.antMatchers("/yes").hasAuthority("10001")
.antMatchers("/no").hasAuthority("00000")
.anyRequest().authenticated();
}
}
而且您将不再需要 @PreAuthorize
注释,也不再需要 .xml 配置文件(security.xml、web.xml 等...)
祝你好运;)
我正在使用 Spring 安全性(Spring 启动应用程序)和 AngularJS,并且我正在尝试 allow/deny 访问基于用户授予的特定映射当局。
User.java
public class User implements UserDetails {
...
private String username;
private String password;
private boolean enabled;
private List<GrantedAuthority> grantedAuthorities;
public User(...) {...}
private class Permission implements GrantedAuthority {
String permission;
public Permission(String permission) {
this.permission = permission;
}
@Override
public String getAuthority() {
return permission;
}
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return grantedAuthorities;
}
...
}
此外,我有自己的 UserDetailsService
实现(方法 loadUserByUsername(String username)
),它使用数据库中的数据填充用户数据。
前面提到的映射是:
@RequestMapping("yes")
public void doesHaveAuthority() {yes();}
@PreAuthorize("hasAuthority('10001')")
private void yes() {}
@RequestMapping("no")
public void doesntHaveAuthority() {no();}
@PreAuthorize("hasAuthority('00000')")
private void no() {}
用户确实有权限“10001”,但没有权限“00000”,应该允许访问 /yes
,但不允许访问 /no
。不幸的是,两条路径都是允许的。
我有 spring-security-config
作为提到的 Maven 依赖项 here。
我的WEB-INF/web.xml
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/security.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
和WEB-INF/security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<context:component-scan base-package="com.mycompany.project" />
<global-method-security pre-post-annotations="enabled" />
</beans:beans>
所以,总结一下:UserDetailsService 实现有效(我可以使用用户凭据登录,记录器打印授予的权限,所以我知道它们在那里),但用户可以访问两者 yes
和 /no
路径实际上 he/she 不应该能够访问 /no
因为 he/she 没有权限(许可)“00000”.
也许我的 xml 配置不正确或根本没有被读取。
感谢您的宝贵时间
更新 正如 M. Deinum 在评论中所说 Spring 引导忽略 web.xml 和 security.xml 文件。解决方案是修改扩展 WebSecurityConfigurerAdapter
的 SecurityConfiguration
并添加具有相应权限的相应 antMatchers。
示例:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().and()
.authorizeRequests()
.antMatchers("/login.html", "/index.html", "/").permitAll()
.antMatchers("/yes").hasAuthority("10001")
.antMatchers("/no").hasAuthority("00000")
.anyRequest()
.authenticated().and()
.addFilterAfter(new CSRFHeaderFilter(), CsrfFilter.class)
.csrf().csrfTokenRepository(csrfTokenRepository());
}
用户"We are Borg"要求我post解决方案作为答案所以这里是:
基本上,因为我的应用程序是 Spring 引导应用程序,所以它被忽略了(忽略了我的 .xml 配置文件)。解决方案非常简单:扩展 WebSecurityConfigurerAdapter
并覆盖 configure(HttpSecurity)
方法。覆盖它时,请确保用户具有访问路径(antMatchers)的权限 and/or 权限。它应该看起来像这样:
SecurityConfiguration.java
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().and()
.authorizeRequests()
.antMatchers("/login.html", "/index.html", "/").permitAll()
.antMatchers("/yes").hasAuthority("10001")
.antMatchers("/no").hasAuthority("00000")
.anyRequest().authenticated();
}
}
而且您将不再需要 @PreAuthorize
注释,也不再需要 .xml 配置文件(security.xml、web.xml 等...)
祝你好运;)