我想在我的 J2EE 项目中包含 SSO。我正在尝试找到一个解决方案,它不需要我的应用程序服务器以外的其他服务器。
这是环境:
- Glassfish v3.1.2
- 2 个使用 Spring MVC / Security 的相同项目(比如说 project1 和 project2)
项目实施什么:
- 一个简单的ajax登录表单
具有登录和测试方法的控制器:
@Controller public class ProjectController { public static final String REMEMBER_ME_ACTIVE = "on"; @Autowired SecurityContextRepository repository; @Autowired RememberMeServices rememberMeServices; @RequestMapping(value = "/login", method = RequestMethod.GET) public Object login(HttpServletRequest request, HttpServletResponse response) { System.out.println("[GET] login"); System.out.println(SecurityContextHolder.getContext().getAuthentication()); System.out.println(request.getSession().getId()); return new ModelAndView("login"); } @RequestMapping(value = "/login", method = RequestMethod.POST) @ResponseBody public Object login(@RequestParam("j_username") String username, @RequestParam("j_password") String password, @RequestParam("_spring_security_remember_me") String rememberMe, HttpServletRequest request, HttpServletResponse response) { System.out.println("[POST] login"); System.out.println(SecurityContextHolder.getContext().getAuthentication()); System.out.println(request.getSession().getId()); try { UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password); SecurityContext context = SecurityContextHolder.getContext(); context.setAuthentication(token); repository.saveContext(context, request, response); if (REMEMBER_ME_ACTIVE.equals(rememberMe)) { rememberMeServices.loginSuccess(request, response, token); } return "OK"; } catch (BadCredentialsException e) { return "BadCredentialsException"; } catch (Exception e) { e.printStackTrace(); return "Exception : " + e.getMessage(); } } @RequestMapping(value = "/test", method = RequestMethod.GET) public Object test(HttpServletRequest request, HttpServletResponse response) { System.out.println("[GET] test"); System.out.println(SecurityContextHolder.getContext().getAuthentication()); System.out.println(request.getSession().getId()); return new ModelAndView("test"); } }
弹簧安全.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> <!-- security config --> <http auto-config="false" use-expressions="true" > <http-basic/> <intercept-url pattern="/login" access="hasRole('ROLE_ANONYMOUS')"/> <intercept-url pattern="/**" access="hasAnyRole('ROLE_USER')" /> <form-login login-page="/login" login-processing-url="/spring/login" authentication-failure-url="/login" default-target-url="/" always-use-default-target="true" /> <remember-me services-ref="tokenBasedRememberMeServices" key="XXXXXX_1234567890" use-secure-cookie="true" /> <logout logout-url="/spring/logout" invalidate-session="false" logout-success-url="/login" /> <session-management invalid-session-url="/login" session-fixation-protection="newSession"> <concurrency-control max-sessions="3" error-if-maximum-exceeded="false" expired-url="/login" session-registry-ref="sessionRegistry" /> </session-management> </http> <beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" /> <!-- authentication config --> <authentication-manager> <authentication-provider ref="userAuthenticationProvider"/> </authentication-manager> <beans:bean id="userAuthenticationProvider" class="be.xxx.spring.security.UserAuthenticationProvider" /> <beans:bean id="tokenBasedRememberMeServices" class="be.xxx.spring.security.TokenBasedRememberMeServices"> <beans:constructor-arg name="key" value="XXXXXX_1234567890"/> <beans:constructor-arg name="userDetailsService" ref="userDetailsService"/> </beans:bean> <beans:bean id="userDetailsService" class="be.xxx.spring.security.UserDetailsService" /> </beans:beans>
到目前为止,我发现 Glassfish 支持此处所写的 SSO,但它似乎无法与 Spring Security 一起使用。在 project1 中登录时,我看不到 JSESSIONIDSSO。因此,当我启动 project2 时,它会向我发送登录表单...还尝试在 web.xml 中指定相同的领域名称,但没有更改。
经过一番谷歌搜索,我发现了一些关于 PreAuthenticationFilter 的东西,但我真的不知道如何用这个实现 SSO 解决方案。
你能帮我找出解决办法吗?
谢谢,
烟