SpringSecurity2.0的容易SSO
项目需要做一个简单的SSO到我们用SpringSecurity2.0的系统,因为没有统一的用户LDAP,采用post用户名密码的方式。现在要处理的就是2件事,一是能够post通过验证,二是验证通过要跳转到指定的页面。一很好实现: http://localhost:8081/j_spring_security_check?j_username=admin&j_password=1,采用的默认配置就可以通过验证。简单看一下spring源码,AuthenticationProcessingFilter是默认filterChain中的一个,由它来处理form方式的验证,验证代码如下:
public Authentication attemptAuthentication(HttpServletRequest request) throws AuthenticationException { String username = obtainUsername(request); String password = obtainPassword(request); if (username == null) { username = ""; } if (password == null) { password = ""; } username = username.trim(); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); // Place the last username attempted into HttpSession for views HttpSession session = request.getSession(false); if (session != null || getAllowSessionCreation()) { request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, username); } // Allow subclasses to set the "details" property setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest); }
protected String obtainUsername(HttpServletRequest request) { return request.getParameter(usernameParameter); }
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username"; public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password"; public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY; private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
public String getDefaultFilterProcessesUrl() { return "/j_spring_security_check"; }
url中的3个参数代码中都出现了。
第二个问题就复杂一点了,配置的默认页面是index.jsp,现在要跳转到其它页面。查不到文档,还是自己看源码。AuthenticationProcessingFilter extends了AbstractProcessingFilter,这个类有很多与配置对应的属性,一个我们需要的属性就是targetUrlResolver:
private TargetUrlResolver targetUrlResolver = new TargetUrlResolverImpl();
这里就是处理验证后的跳转,看默认的TargetUrlResolverImpl类实现:
public String determineTargetUrl(SavedRequest savedRequest, HttpServletRequest currentRequest, Authentication auth) { String targetUrl = currentRequest.getParameter(targetUrlParameter); if (StringUtils.hasText(targetUrl)) { try { return URLDecoder.decode(targetUrl, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new IllegalStateException("UTF-8 not supported. Shouldn't be possible"); } } if (savedRequest != null) { if (!justUseSavedRequestOnGet || savedRequest.getMethod().equals("GET")) { targetUrl = savedRequest.getFullRequestUrl(); } } return targetUrl; }
这里targetUrl也是先getParameter,这意味着通过url参数指定跳转页面成为了可能
public static String DEFAULT_TARGET_PARAMETER = "spring-security-redirect"; private String targetUrlParameter = DEFAULT_TARGET_PARAMETER;
找到了这个参数,spring-security-redirect,尝试url:
http://localhost:8081/j_spring_security_check?j_username=admin&j_password=1&spring-security-redirect=draft.do
验证通过并跳转到了相应的页面,这样没有增加代码和配置就完成了,也对SpringSecurity有了直观的认识。SpringSecurity也提供其它方式的sso,等有机会再好好研究。