我正在尝试使用
Spring-boot和Dave Syer样本实现Spring Security Oauth2的sso
我想使用我的custom server提供商,它工作正常.
对于客户端,我希望用户在尝试访问客户端站点(例如localhost:8080 /)时进行身份验证(因此重定向到OAuth2 url),并在进行身份验证后重定向回index.html文件.我还想在index.html文件中的链接上实现用户注销.
我想出了以下客户端sso客户端:
package org.ikane; import java.io.IOException; import java.security.Principal; import java.util.Arrays; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.csrf.CsrfFilter; import org.springframework.security.web.csrf.CsrfToken; import org.springframework.security.web.csrf.CsrfTokenRepository; import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository; import org.springframework.stereotype.Component; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.util.WebUtils; @SpringBootApplication @Controller public class DemoSsoOauth2ClientApplication implements CommandLineRunner { private static final Logger logger = LoggerFactory.getLogger(DemoSsoOauth2ClientApplication.class); @Override public void run(String... arg0) throws Exception { SecurityContext securityContext = SecurityContextHolder.getContext(); try { Authentication authentication = securityContext.getAuthentication(); logger.info(authentication.getDetails().toString()); SecurityContextHolder.clearContext(); } catch (Exception e) { logger.error("Error", e); } } public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(DemoSsoOauth2ClientApplication.class, args); ConfigurableEnvironment env = applicationContext.getEnvironment(); logger.info("\n\thttp://localhost:{}{}\n\tProfiles:{}\n", StringUtils.defaultIfEmpty(env.getProperty("server.port"), "8080"), StringUtils.defaultIfEmpty(env.getProperty("server.contextPath"), "/"), Arrays.toString(env.getActiveProfiles())); } @RequestMapping(value="/") public String home() { return "index"; } @RequestMapping(value="/user") @ResponseBody public Principal user(Principal user) { return user; } /** * The Class OAuthConfiguration that sets up the OAuth2 single sign on * configuration and the web security associated with it. */ @Component @Controller @EnableOAuth2Sso protected static class OAuthClientConfiguration extends WebSecurityConfigurerAdapter { private static final String CSRF_COOKIE_NAME = "XSRF-TOKEN"; private static final String CSRF_ANGULAR_HEADER_NAME = "X-XSRF-TOKEN"; @Override public void configure(HttpSecurity http) throws Exception { http.antMatcher("/**").authorizeRequests() .antMatchers("/index.html", "/").permitAll().anyRequest() .authenticated().and().csrf().csrfTokenRepository(csrfTokenRepository()) .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class); } private Filter csrfHeaderFilter() { return new OncePerRequestFilter() { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName()); if (csrf != null) { Cookie cookie = WebUtils.getCookie(request, CSRF_COOKIE_NAME); String token = csrf.getToken(); if (cookie == null || token != null && !token.equals(cookie.getValue())) { cookie = new Cookie(CSRF_COOKIE_NAME, token); cookie.setPath("/"); response.addCookie(cookie); } } filterChain.doFilter(request, response); } }; } /** * Angular sends the CSRF token in a custom header named "X-XSRF-TOKEN" * rather than the default "X-CSRF-TOKEN" that Spring security expects. * Hence we are now telling Spring security to expect the token in the * "X-XSRF-TOKEN" header.
* * This customization is added to thecsrf()
filter. * * @return */ private CsrfTokenRepository csrfTokenRepository() { HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository(); repository.setHeaderName(CSRF_ANGULAR_HEADER_NAME); return repository; } } }
你可以找到一个GitHub source.关于如何实现这个用例的任何提示?
提前致谢
最佳答案 >要使您的客户端应用程序重定向到授权服务器,只需添加
WebSecurityConfigurerAdapter上的注释@ EnableOAuth2Sso和
在您的属性文件中放置正确的OAuth2配置(client-id,secret,access token uri …).
(我假设您的客户端应用程序也使用Spring Boot)
>要结束用户的会话,您必须重定向到授权服务器中的端点并以编程方式注销,如
this post所示.
我创建了一个带有示例应用程序的repository on github,它具有您正在寻找的功能.
请检查一下,如果有帮助,请告诉我.