spring-security - Spring Security OAuth2 SSO 与自定义提供程序 + 注销

标签 spring-security spring-boot single-sign-on spring-security-oauth2

我正在尝试使用 Spring-boot 和 Dave Syer 示例通过 Spring Security Oauth2 实现 sso

我想用我的 custom server供应商,它工作正常。

对于客户端,我希望用户在尝试访问客户端站点(例如 localhost:8080/)时进行身份验证(因此重定向到 OAuth2 url)并在身份验证后重定向回 index.html 文件。我还想在用户访问 index.html 文件中的链接时实现注销。

我想出了以下客户端 sso 客户端:

包 org.ikane;

导入 java.io.IOException;
导入 java.security.Principal;
导入 java.util.Arrays;

导入 javax.servlet.Filter;
导入 javax.servlet.FilterChain;
导入 javax.servlet.ServletException;
导入 javax.servlet.http.Cookie;
导入 javax.servlet.http.HttpServletRequest;
导入 javax.servlet.http.HttpServletResponse;

导入 org.apache.commons.lang3.StringUtils;
导入 org.slf4j.Logger;
导入 org.slf4j.LoggerFactory;
导入 org.springframework.boot.CommandLineRunner;
导入 org.springframework.boot.SpringApplication;
导入 org.springframework.boot.autoconfigure.SpringBootApplication;
导入 org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
导入 org.springframework.context.ConfigurableApplicationContext;
导入 org.springframework.core.env.ConfigurableEnvironment;
导入 org.springframework.security.config.annotation.web.builders.HttpSecurity;
导入 org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
导入 org.springframework.security.core.Authentication;
导入 org.springframework.security.core.context.SecurityContext;
导入 org.springframework.security.core.context.SecurityContextHolder;
导入 org.springframework.security.web.csrf.CsrfFilter;
导入 org.springframework.security.web.csrf.CsrfToken;
导入 org.springframework.security.web.csrf.CsrfTokenRepository;
导入 org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
导入 org.springframework.stereotype.Component;
导入 org.springframework.stereotype.Controller;
导入 org.springframework.web.bind.annotation.RequestMapping;
导入 org.springframework.web.bind.annotation.ResponseBody;
导入 org.springframework.web.filter.OncePerRequestFilter;
导入 org.springframework.web.util.WebUtils;

@SpringBootApplication
@ Controller
公共(public)类 DemoSsoOauth2ClientApplication 实现 CommandLineRunner {

私有(private)静态最终记录器记录器 = LoggerFactory.getLogger(DemoSsoOauth2ClientApplication.class);

@覆盖
公共(public)无效运行(字符串... arg0)抛出异常{
SecurityContext securityContext = SecurityContextHolder.getContext();
尝试 {
身份验证 authentication = securityContext.getAuthentication();
logger.info(authentication.getDetails().toString());

SecurityContextHolder.clearContext();
} 捕获(异常 e){
logger.error("错误", e);
}
}

公共(public)静态无效主(字符串 [] 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)字符串家(){
返回“索引”;
}

@RequestMapping(value="/user")
@ResponseBody
公共(public)主体用户(主体用户){
返回用户;
}

/**
* 设置 OAuth2 单点登录的 OAuthConfiguration 类
* 配置和与之相关的网络安全。
*/
@成分
@ Controller
@EnableOAuth2Sso
protected 静态类 OAuthClientConfiguration 扩展了 WebSecurityConfigurerAdapter {

private static final String CSRF_COOKIE_NAME = "XSRF-TOKEN";
private static final String CSRF_ANGULAR_HEADER_NAME = "X-XSRF-TOKEN";

@覆盖
公共(public)无效配置(HttpSecurity http)抛出异常{
http.antMatcher("/**").authorizeRequests()
.antMatchers("/index.html", "/").permitAll().anyRequest()
.authenticated().and().csrf().csrfTokenRepository(csrfTokenRepository())
.and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
}

私有(private)过滤器 csrfHeaderFilter() {
返回新的 OncePerRequestFilter() {

@覆盖
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
抛出 ServletException,IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
如果(CSRF!=空){
Cookie cookie = WebUtils.getCookie(request, CSRF_COOKIE_NAME);
String token = csrf.getToken();
if (cookie == null || token != null
&& !token.equals(cookie.getValue())) {
cookie = 新的 Cookie(CSRF_COOKIE_NAME, token );
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(请求,响应);
}
};
}

/**
* Angular 在名为“X-XSRF-TOKEN”的自定义 header 中发送 CSRF token
* 而不是 Spring 安全所期望的默认“X-CSRF-TOKEN”。
* 因此,我们现在告诉 Spring security 期待 token 中的
* "X-XSRF-TOKEN" header 。
*
* 此自定义添加到 csrf()筛选。
*
* @返回
*/
私有(private) CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository 存储库 = 新的 HttpSessionCsrfTokenRepository();
repository.setHeaderName(CSRF_ANGULAR_HEADER_NAME);
返回存储库;
}
}

}

您可以找到 GitHub source .有关如何实现此用例的任何提示?

提前致谢

最佳答案

  • 要使您的客户端应用程序重定向到授权服务器,只需添加
    注释@EnableOAuth2Sso在您的 WebSecurityConfigurerAdapter
    将正确的 OAuth2 配置(客户端 ID、 secret 、访问 token uri...)放在您的属性文件中。
    (我假设您的客户端应用程序也在使用 Spring Boot)
  • 要结束用户的 session ,您必须重定向到授权服务器中的端点并以编程方式注销,如 this post 所示。 .

  • 我创建了一个 repository on github使用具有您正在寻找的功能的示例应用程序。

    请检查一下,如果对您有帮助,请告诉我。

    关于spring-security - Spring Security OAuth2 SSO 与自定义提供程序 + 注销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34379498/

    相关文章:

    grails - Spring Security核心和filterChain chainMap问题

    spring-boot - Spring 安全: unable to enable permitAll() to POST API

    spring-security - 如何在不使用spring boot security进行编码的情况下获取用户名和输入的密码

    electron - Electron如何实现单点登录?

    azure - 允许用户更改基于密码的 sso 密码

    perl - 删除了自定义 HTTP header 字段

    java - Spring 数据休息: How to publish a user management api

    jsf - session 过期后 Spring Security 登录重定向到最后一个 JSF ajax 请求并以纯文本形式显示其 <partial-response> XML 响应

    java - 无法使用第二个数据源运行 Spring JUnit 测试

    java - 查询用户输入,然后存储在数据库中,然后显示在页面上