【问题标题】:How to add custom filter after user authorize in spring application用户在spring应用程序中授权后如何添加自定义过滤器
【发布时间】:2012-07-05 11:36:33
【问题描述】:

我是 Spring Security 3 的新手。我正在使用角色让用户登录。

我想在用户被授权进入应用程序后添加一些会话值。也许我需要一些过滤器,以便它重定向到我添加一些会话值的方法。我已经配置了我的 security.xml 文件,但我不确定我是否在做正确的事情。这个方向的任何例子都会有所帮助。我应该使用哪个过滤器类?应该如何配置security.xml文件?

<custom-filter ref="authenticationFilter" after="FORM_LOGIN_FILTER "/>

<beans:bean id="authenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
    <beans:property name="filterProcessesUrl" value="/j_spring_security_check" />
    <beans:property name="authenticationManager" ref="authenticationManager" />
    <beans:property name="authenticationSuccessHandler" ref="successHandler" />
</beans:bean> 

<beans:bean id="successHandler" class="org.dfci.sparks.datarequest.security.CustomAuthorizationFilter"/>

我的过滤器类方法我需要添加一些会话值。

public class CustomAuthorizationFilter implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
            HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException {
        Set<String> roles = AuthorityUtils.authorityListToSet(authentication
                .getAuthorities());
        if (roles.contains("ROLE_USER")) {
            request.getSession().setAttribute("myVale", "myvalue");
        }
    }
}

编辑代码

我已经修改了我的 security.xml 文件和类文件

<custom-filter ref="authenticationFilter" after="FORM_LOGIN_FILTER "/>  
public class CustomAuthorizationFilter extends GenericFilterBean {

    /*
     * ServletRequestAttributes attr = (ServletRequestAttributes)
     * RequestContextHolder.currentRequestAttributes(); HttpSession
     * session=attr.getRequest().getSession(true);
     */
    @Autowired
    private UserService userService;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        try {
            chain.doFilter(request, response);

                    HttpServletRequest req = (HttpServletRequest) request;
                    HttpSession session = req.getSession(true);
                    Authentication authentication = SecurityContextHolder
                            .getContext().getAuthentication();
                    Set<String> roles = AuthorityUtils
                            .authorityListToSet(authentication.getAuthorities());
                    User user = null;                   
                        if (true) {
                            session.setAttribute("Flag", "Y");
                        } 
            }

        } catch (IOException ex) {
            throw ex;
        }
    }

}

调用每个 URL。当用户通过身份验证时,是否只调用一次过滤方法?

【问题讨论】:

  • 以上代码有什么问题?您没有在登录成功 url 中获取会话 myValue 属性吗?
  • @SunilChavan : 在用户认证之前调用这个过滤器。
  • 你怎么能这么说?请参阅 (API)[static.springsource.org/spring-security/site/docs/3.0.x/apidocs/… 详细信息。它清楚地表明在成功验证后它会调用 onAuthenticationSuccess 方法
  • @SunilChavan,谢谢,链接无效。

标签: spring spring-security


【解决方案1】:

终于解决了我的问题。我没有使用过滤器,而是添加了只为成功登录调用的处理程序。

在security.xml中添加以下行

<form-login login-page="/" authentication-failure-url="/?login_error=1" default-target-url="/" always-use-default-target="false"  
        authentication-success-handler-ref="authenticationSuccessHandler"/>
        <logout />

<beans:bean id="authenticationSuccessHandler" class="security.CustomSuccessHandler"/>

我还添加了一个添加会话属性的自定义处理程序。

package security;

import java.io.IOException;
import java.security.GeneralSecurityException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;

public class CustomSuccessHandler extends
            SavedRequestAwareAuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(final HttpServletRequest request,
            final HttpServletResponse response, final Authentication authentication)
            throws IOException, ServletException {
        super.onAuthenticationSuccess(request, response, authentication);

        HttpSession session = request.getSession(true);

        try {
            if (CurrentUser.isUserInRole("USER")) {
                session.setAttribute("Flag", "user");
            } 
        } catch (Exception e) {
            logger.error("Error in getting User()", e);
        } 
    }

}

【讨论】:

  • 我正在从hear调用一个通用函数,但它返回运行jdbctemplate的空指针异常。
【解决方案2】:

您可以使用标准的 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>

<!-- Pay attention to the url-pattern -->
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
    <!-- <dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher> -->
</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>

【讨论】:

  • 感谢您提供示例。我遵循与您提到的相同的步骤。我已经修改了我的代码,但是过滤器方法调用了每个 url。用户通过身份验证时是否只调用一次?
  • 如果我理解正确,您应该为过滤器设置正确的 url-pattern(例如您的登录页面 /login.jsp)。在这种情况下,过滤器将只拦截对您的登录页面的请求。对于其他 url 过滤器将不会执行。
  • 我尝试使用 /login.jsp,但它仍然没有调用我的过滤方法仅用于登录。
  • 其实,我觉得你错过了什么。我刚刚测试了这个案例。我有两个页面:login.jsp 和 customPage.jsp(gwt 应用程序)。一切都很完美。过滤器仅拦截 /login.jsp 的请求。
  • 感谢您的帮助。请查看我的回答。对于登录页面,我们只有“/”。我已经使用处理程序实现了它。请在下面查看我的答案。
猜你喜欢
  • 1970-01-01
  • 2013-03-26
  • 2021-10-31
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 2014-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多