Я хочу получить некоторую информацию за запрос, поэтому я думаю вместо того, чтобы иметь функцию для каждого запроса и получать эту информацию из запросов отдельно, лучше иметь фильтр.
Поэтому каждый запрос должен передать этот фильтр, и я получаю то, что хочу.
Возникает вопрос: как написать собственный фильтр?
Предположим, что он не похож на предопределенные фильтры безопасности spring, и он совершенно новый.
Как написать собственный фильтр в spring безопасности?
Ответ 1
Вы можете использовать стандартный Java-фильтр. Просто поместите его после фильтра проверки подлинности в web.xml(это означает, что он будет идти позже в цепочке фильтров и будет вызван после цепочки фильтров безопасности).
public class CustomFilter implements Filter{
@Override
public void destroy() {
// Do nothing
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
if (roles.contains("ROLE_USER")) {
request.getSession().setAttribute("myVale", "myvalue");
}
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// Do nothing
}
}
Фрагмент web.xml:
<!-- The Spring Security Filter Chain -->
<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>
<!-- Your filter definition -->
<filter>
<filter-name>customFilter</filter-name>
<filter-class>com.yourcompany.test.CustomFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>customFilter</filter-name>
<url-pattern>/VacationsManager.jsp</url-pattern>
</filter-mapping>
Также вы можете добавить обработчик, который будет вызываться после успешного входа (вам нужно расширить SavedRequestAwareAuthenticationSuccessHandler). Посмотрите здесь, как это сделать. И я думаю, что это еще лучше.
ОБНОВЛЕНО:
Или вы можете иметь этот фильтр в конце ваших фильтров безопасности следующим образом:
<security:filter-chain-map>
<sec:filter-chain pattern="/**"
filters="
ConcurrentSessionFilterAdmin,
securityContextPersistenceFilter,
logoutFilterAdmin,
usernamePasswordAuthenticationFilterAdmin,
basicAuthenticationFilterAdmin,
requestCacheAwareFilter,
securityContextHolderAwareRequestFilter,
anonymousAuthenticationFilter,
sessionManagementFilterAdmin,
exceptionTranslationFilter,
filterSecurityInterceptorAdmin,
MonitoringFilter"/> <!-- Your Filter at the End -->
</security:filter-chain-map>
И чтобы иметь свой фильтр, вы можете использовать это:
public class MonitoringFilter extends GenericFilterBean{
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//Implement this Function to have your filter working
}
Ответ 2
Просто выбросьте это в микс; как насчет использования custom-filter
внутри элемента http
:
<security:http auto-config="false" ...>
...
<security:custom-filter position="FORM_LOGIN_FILTER" ref="MyCustomFilter" />
</security:http>