如何以编程方式检查某个 URL 是不是需要使用 Spring Security 进行身份验证?
Posted
技术标签:
【中文标题】如何以编程方式检查某个 URL 是不是需要使用 Spring Security 进行身份验证?【英文标题】:How to programmatically check if a certain URL needs authentication with Spring Security?如何以编程方式检查某个 URL 是否需要使用 Spring Security 进行身份验证? 【发布时间】:2014-08-13 16:03:23 【问题描述】:有没有办法使用 Spring Security (v 3.1.x) 以编程方式获取某个 URL 的授权规则?
我的意思是...假设我设置:
<security:intercept-url pattern="/**" access="isAuthenticated()" />
在我的配置中。
在处理/internal/**
路径的控制器中,我想知道我是否需要身份验证才能访问某个路径。像这样的方法:
boolean isAuthenticationRequired(String ulr);
可能有用。
我可以通过SecurityContextHolder
获得这些信息吗?
UPDATE四处搜索,似乎关键可能是SecurityMetadataSource
...
【问题讨论】:
这不是您问题的答案,而是可能对您有所帮助的提示。尝试在身份验证期间引发异常。分析堆栈跟踪并找到执行身份验证的代码。环顾四周,您将看到所需的 API。祝你好运。 @AlexR 感谢您的建议。 没问题。祝你好运。找到解决方案后,请发布“正确”的自我答案。 @AlexR 我希望能找到它... :D 【参考方案1】:如果您使用基于模式的配置,我认为这是获取 SecurityMetadataSource 和规则的唯一(也是丑陋的)方法:
@Autowired
private ApplicationContext applicationContext;
public void someMethod()
FilterSecurityInterceptor fsi = applicationContext.getBean(org.springframework.security.web.access.intercept.FilterSecurityInterceptor.class);
FilterInvocationSecurityMetadataSource sms = fsi.getSecurityMetadataSource();
try
Field field = sms.getClass().getDeclaredField("requestMap");
field.setAccessible(true);
Map<RequestMatcher, Collection<ConfigAttribute>> requestMap = (Map<RequestMatcher, Collection<ConfigAttribute>>)field.get(sms);
Set<Entry<RequestMatcher, Collection<ConfigAttribute>>> entrySet = requestMap.entrySet();
for (Entry<RequestMatcher, Collection<ConfigAttribute>> entry : entrySet)
AntPathRequestMatcher path = (AntPathRequestMatcher)entry.getKey();
System.out.println(path.getPattern());
//prints sthg like /action/index
Collection<ConfigAttribute> roles = entry.getValue();
System.out.println(roles);
//[ROLE_USER,ROLE_ADMIN]
catch (Exception e)
//TODO
e.printStackTrace();
使用它,您可以轻松地编写实用程序服务来检查 URL。
替代方案更简洁,但最终更冗长:如果您不使用基于模式的配置,则可以更轻松地访问包含映射的 bean (interceptedUrls):
<bean id="fsi" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
<property name="securityMetadataSource" ref="interceptedUrls"/>
</bean>
<sec:filter-invocation-definition-source id="interceptedUrls">
<sec:intercept-url pattern="/action/login" access="ROLE_ANONYMOUS"/>
<sec:intercept-url pattern="/action/passwordReset" access="ROLE_ANONYMOUS"/>
<sec:intercept-url pattern="/action/index" access="ROLE_ADMIN"/>
...
希望这会有所帮助!
【讨论】:
+1 我会避免反思,但我认为这可能是一个好的(丑陋的)建议。谢谢。以上是关于如何以编程方式检查某个 URL 是不是需要使用 Spring Security 进行身份验证?的主要内容,如果未能解决你的问题,请参考以下文章
C#:如何以编程方式检查 Web 服务是不是已启动并正在运行?