在spring security 3.0中,我们正在使用AuthenticationProcessingFilter
类,我们使用determineTargetUrl()
方法,该方法根据不同的角色返回url。
现在,我们正在转向Spring security 3.1.0.RC3,我现在应该如何确定基于不同角色的URL,因为AuthenticationProcessingFilter
类已从新版本中删除。任何人都可以请给我一些简短的代码,以便我可以实现自定义过滤器以重定向到不同角色的不同页面。
答案 0 :(得分:21)
根据角色确定目标网址的最佳方法是在Spring Security配置中指定目标网址,如下所示。这将适用于Spring 3.0或3.1
<http>
...
<form-login login-page="/login" default-target-url="/default"/>
</http>
然后创建一个处理default-target-url的控制器。控制器应根据滚动重定向或转发。下面是使用Spring MVC的示例,但任何类型的控制器都可以工作(即Struts,Servlet等)。
@Controller
public class DefaultController {
@RequestMapping("/default")
public String defaultAfterLogin(HttpServletRequest request) {
if (request.isUserInRole("ROLE_ADMIN")) {
return "redirect:/users/sessions";
}
return "redirect:/messages/inbox";
}
}
这种方法的优点是它没有与任何特定的Security实现相结合,它没有耦合到任何特定的MVC实现,并且它可以轻松地与Spring Security命名空间配置一起工作。在我今年在SpringOne上展示的SecureMail项目中可以找到一个完整的例子。
另一种方法是您可以创建自定义AuthenticationSuccessHandler。实现可能会扩展SavedRequestAwareAuthenticationSuccessHandler,它是默认的AuthenticationSuccessHandler。然后可以使用命名空间进行连接,如下所示。
<sec:http>
<sec:form-login authentication-success-handler-ref="authSuccessHandler"/>
</sec:http>
<bean:bean class="example.MyCustomAuthenticationSuccessHandler"/>
我不建议这样做,因为它与Spring Security API相关联,最好在可能的情况下避免这种情况。
答案 1 :(得分:0)
在成功认证后,使用自定义认证成功处理程序根据用户角色指定重定向。
您需要创建以下自定义身份验证成功处理程序:
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;
public class CustomeAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication) throws IOException {
handle(request, response, authentication);
}
protected void handle(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws IOException {
String targetUrl = determineTargetUrl(authentication);
if (response.isCommitted()) {
return;
}
redirectStrategy.sendRedirect(request, response, targetUrl);
}
protected String determineTargetUrl(Authentication authentication) {
boolean isTeacher = false;
boolean isAdmin = false;
Collection<? extends GrantedAuthority> authorities
= authentication.getAuthorities();
for (GrantedAuthority grantedAuthority : authorities) {
if (grantedAuthority.getAuthority().equals("ROLE_USER")) {
isTeacher = true;
break;
} else if (grantedAuthority.getAuthority().equals("ROLE_ADMIN")) {
isAdmin = true;
break;
}
}
if (isTeacher) {
return "/user/account";
} else if (isAdmin) {
return "/admin/account";
} else {
throw new IllegalStateException();
}
}
public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
this.redirectStrategy = redirectStrategy;
}
protected RedirectStrategy getRedirectStrategy() {
return redirectStrategy;
}
}
然后修改spring security xml文件并定义您的bean并使用它
<bean id="customeAuthenticationSuccessHandler"
class="com.test.CustomeAuthenticationSuccessHandler"/>
<security:http auto-config="true" use-expressions="false">
<security:form-login login-page="/sign-in" login-processing-url="/sign-in" username-parameter="username"
password-parameter="password"
authentication-success-handler-ref="customeAuthenticationSuccessHandler"
always-use-default-target="true"
authentication-failure-url="/sign-in?error=true"/>
<security:logout logout-url="/logout" logout-success-url="/"/>
..
..
</security:http>