Я использую безопасность Spring, и у меня есть настраиваемый фильтр авторизации без явного сопоставления URL-адресов. Я добавил свой фильтр авторизации после UsernamePasswordAuthenticationFilter.class.
Проблема с этим подходом заключается в том, что даже шаблоны URL, которые разрешены или разрешены при аутентификации, проходят через мой фильтр авторизации. Я не хочу явно настраивать сопоставление моего фильтра в фильтре авторизации, поскольку считаю, что это избыточно (уже присутствует в WebSecurityConfigurerAdapter). Могу ли я в любом случае получить доступ к метаданным Spring Security или каким-либо другим способом пропустить фильтр авторизации для URL-адресов, которые помечены как permissionAll () или Authenticated ()?
public class AuthorizationFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
//Calls a webservice to fetch the authorities based on the URL pattern.
//Adds the authentication principal with Authorities to SecurityContextHolder.
}
public void init(FilterConfig config) throws ServletException {
}
}
@chaoluo Я добавил свой фильтр авторизации и в комментариях указал, что он будет делать.
Я думаю, вы можете ввести свой собственный сопоставитель запросов в этот фильтр, чтобы пропустить эти URL-адреса
да. Это работает. Но я хотел бы использовать для этого саму конфигурацию безопасности Spring HttpSecurity. Думаю, я нашел способ. Я могу зарегистрировать ObjectPostProcessor и извлечь информацию securityMetadataSource из FilterSecurityInterceptor. Спасибо за быстрый ответ @chaoluo.
Я решил это, расширив WebExpressionVoter, как показано ниже:
public class CustomAuthoritiesVoter extends WebExpressionVoter {
private static final String SUPPORTED_CLASS = "org.springframework.security.web.access.expression.WebExpressionConfigAttribute";
@Override
public int vote(Authentication authentication, FilterInvocation fi, Collection<ConfigAttribute> attributes) {
String exp = getExpressionString(attributes);
if (null != exp && !StringUtils.equalsAny(exp, "authenticated", "permitAll")) {
//Call service to fetch the authorities based on the userID and URL
//Set Authentication principal along with fetched Authorities using SecurityContextHolder
}
return super.vote(authentication, fi, attributes);
}
private String getExpressionString(Collection<ConfigAttribute> attributes) {
try {
for (ConfigAttribute attribute : attributes) {
if (attribute.getClass().isAssignableFrom(Class.forName(SUPPORTED_CLASS))) {
return attribute.toString();
}
}
} catch (ClassNotFoundException e) {
log.warn(e.getMessage(), e);
}
return null;
}
}
Не могли бы вы поделиться своим настраиваемым фильтром?