Java 检查经过身份验证的用户是否可以访问URL
我已经使用Java 检查经过身份验证的用户是否可以访问URL,java,spring-boot,spring-security,Java,Spring Boot,Spring Security,我已经使用spring-security-4.2.2设置了spring-boot-1.5.3应用程序,并根据权限配置了受限路径。这些限制与此类似: @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled = true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override pr
spring-security-4.2.2
设置了spring-boot-1.5.3
应用程序,并根据权限配置了受限路径。这些限制与此类似:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/accounts/**", "/roles/**")
.hasAuthority(ADMINISTRATOR)
.and()
.antMatchers("/**")
.hasAuthority(USER)
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.csrf()
.disable();
}
}
简而言之,我希望拥有权限的用户能够访问我的整个web应用程序,除了/accounts/**
和/roles/**
路径之外。此配置工作正常,如果我尝试在没有适当权限的情况下访问这些页面,则会出现预期错误(403)
对于具有USER
权限的用户,我想隐藏一些URL,这样他们就不会发出这些请求并得到403
错误如何检查是否允许用户访问URL
到目前为止,我已经尝试注入webinvocationprivilegeeevaluator
并调用它的是允许的
方法,尽管这似乎不起作用。例如:
// Helper class that returns authentication instance.
Authentication auth = AuthUtils.getAuthentication();
// Don't have permission to access /users, expect to get false result.
boolean res = webInvocationPrivilegeEvaluator.isAllowed("/users", auth );
assert res == false; // fails
而是使用方法检查用户是否具有权限
SecurityContextHolderAwareRequestWrapper.isUserInRole(String role)
而是使用方法检查用户是否具有权限
SecurityContextHolderAwareRequestWrapper.isUserInRole(String role)
通过访问SpringSecurity的内部过滤器,我找到了一个解决这个问题的方法(虽然它可以工作,但看起来确实很粗糙) 首先,我创建了一个帮助器类来检查URL是否可访问:
public final class UrlAuthorization {
private static final Logger LOG = LoggerFactory.getLogger(UrlAuthorization.class);
private final FilterInvocationSecurityMetadataSource securityMetadataSource;
private final AccessDecisionManager accessDecisionManager;
public UrlAuthorization(FilterInvocationSecurityMetadataSource securityMetadataSource,
AccessDecisionManager accessDecisionManager) {
this.securityMetadataSource = securityMetadataSource;
this.accessDecisionManager = accessDecisionManager;
}
public boolean isAccessible(String url) {
Authentication authentication = AuthUtils.getAuthentication();
FilterInvocation invocation = new FilterInvocation(null, url, HttpMethod.GET.name());
Collection<ConfigAttribute> attributes = securityMetadataSource
.getAttributes(invocation);
try {
this.accessDecisionManager.decide(authentication, invocation, attributes);
} catch (AccessDeniedException e) {
LOG.trace("Not allowed to access URL: {}", url, e);
return false;
}
return true;
}
}
最后,我可以这样使用它:
assert urlAuthorization.isAccessible("/accounts") == false;
assert urlAuthorization.isAccessible("/") == true;
通过访问SpringSecurity的内部过滤器,我找到了一个解决这个问题的方法(虽然它可以工作,但看起来确实很粗糙) 首先,我创建了一个帮助器类来检查URL是否可访问:
public final class UrlAuthorization {
private static final Logger LOG = LoggerFactory.getLogger(UrlAuthorization.class);
private final FilterInvocationSecurityMetadataSource securityMetadataSource;
private final AccessDecisionManager accessDecisionManager;
public UrlAuthorization(FilterInvocationSecurityMetadataSource securityMetadataSource,
AccessDecisionManager accessDecisionManager) {
this.securityMetadataSource = securityMetadataSource;
this.accessDecisionManager = accessDecisionManager;
}
public boolean isAccessible(String url) {
Authentication authentication = AuthUtils.getAuthentication();
FilterInvocation invocation = new FilterInvocation(null, url, HttpMethod.GET.name());
Collection<ConfigAttribute> attributes = securityMetadataSource
.getAttributes(invocation);
try {
this.accessDecisionManager.decide(authentication, invocation, attributes);
} catch (AccessDeniedException e) {
LOG.trace("Not allowed to access URL: {}", url, e);
return false;
}
return true;
}
}
最后,我可以这样使用它:
assert urlAuthorization.isAccessible("/accounts") == false;
assert urlAuthorization.isAccessible("/") == true;
如果使用这种方法,我必须在每个URL之前执行此检查(在显示特定URL之前检查用户是否具有角色)。此外,如果我使用此方法,我将不得不将每个URL与特定角色关联,而我已经通过权威机构在
WebSecurityConfig
中这样做了。还要记住,我不是在使用角色,而是在使用权限。所以这种方法对我不起作用。理想情况下,我需要类似于webinvocationprivilegeeevaluator.isAllowed(url)
的东西。我猜它应该可以工作,尽管它似乎总是返回true
,不管我为这个方法提供了什么参数。如果我使用这种方法,我必须在每个URL之前执行这个检查(在显示特定URL之前检查用户是否有角色)。此外,如果我使用此方法,我将不得不将每个URL与特定角色关联,而我已经通过权威机构在WebSecurityConfig
中这样做了。还要记住,我不是在使用角色,而是在使用权限。所以这种方法对我不起作用。理想情况下,我需要类似于webinvocationprivilegeeevaluator.isAllowed(url)
的东西。我猜它应该可以工作,尽管它似乎总是返回true
,而不管我为这个方法提供了什么参数。这可能是个好主意,但对@PreAuthorize不起作用。我得到的FilterSecurityInterceptor只返回带有“authenticated”筛选器的securityMetaDataSource,而所讨论的URL具有@PreAuthorize(“hasRole('ADMIN'))注释。看起来我必须使用不同的过滤器来提供PreAuthorizegreat idea中列出的所有条件,但对@PreAuthorize不起作用。我得到的FilterSecurityInterceptor只返回带有“authenticated”筛选器的securityMetaDataSource,而所讨论的URL具有@PreAuthorize(“hasRole('ADMIN'))注释。看起来我必须使用不同的过滤器来提供预授权中列出的所有条件