spring 如何在spring应用程序中用户授权后添加自定义过滤器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11337997/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add custom filter after user authorize in spring application
提问by Raje
I am a newbie to Spring Security 3. I am using roles for users to login.
我是 Spring Security 3 的新手。我使用角色让用户登录。
I want to add some session value after a user is authorized into the application. Maybe I need some filter so that it redirects to my method which adds some session value. I have configured my security.xml file but I am not sure whether I am doing right things. Any examples in that direction would help. Which Filter Class should I use? How should I configure security.xml file?
我想在用户被授权进入应用程序后添加一些会话值。也许我需要一些过滤器,以便它重定向到我添加一些会话值的方法。我已经配置了我的 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"/>
My filter class method I need to add some session value.
我的过滤器类方法需要添加一些会话值。
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");
}
}
}
Edit Code
编辑代码
I have modified my security.xml file and class file
我已经修改了我的 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;
}
}
}
Which invokes each and every URL. Is it any alternative to call filter method only once when a user is authenticated?
它调用每个 URL。当用户通过身份验证时,是否可以只调用一次过滤器方法?
回答by Raje
Finally I was able to resolved my problem. Instead of using filter I have added handler which only invokes for successful login.
最后我能够解决我的问题。我没有使用过滤器,而是添加了仅调用成功登录的处理程序。
Following line is added in security.xml
在 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"/>
Also I have added one custom handler which add session attribute.
我还添加了一个添加会话属性的自定义处理程序。
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);
}
}
}
回答by dimas
You can use standart java filter (I mean implement Filter interface). Just place it after authentification filter in web.xml (this means that it will go later in the filter chain and will be called after security filter chain).
您可以使用标准 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
}
}
Fragment of web.xml:
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>

