最近在学习单点登录相关,调查了一下目前流行的单点登录解决方案:cas 和 oauth2,文章主要介绍oauth2 单点登录。希望这篇文章能帮助大家学习相关内容。

我们将使用两个单独的应用程序:

  • 授权服务器–这是中央身份验证机制
  • 客户端应用程序:使用SSO的应用程序

简而言之,当用户尝试访问客户端应用程序中的安全页面时,将首先通过身份验证服务器将其重定向为进行身份验证。

而且,我们将使用OAuth2中的“ 授权代码”授予类型来驱动身份验证的委派。

1、身份认证服务器(oauth2-server)

1.1 Maven依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security.oauth/spring-security-oauth2 --><dependency><groupId>org.springframework.security.oauth</groupId><artifactId>spring-security-oauth2</artifactId><version>2.3.5.RELEASE</version>
</dependency>

注意:spring-security-oauth2>=2.3.0,<2.3.4中检测到已知的高严重性安全漏洞,请合理引用依赖

1.2 授权服务器配置

/*** 认证服务器配置* @author ltzhang* @time 2019-11-28*/
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {/*** 注入权限验证控制器 来支持 password grant type*/@Autowiredprivate AuthenticationManager authenticationManager;/*** 注入userDetailsService,开启refresh_token需要用到*/@Autowiredprivate MyUserDetailsService userDetailsService;/*** 数据源*/@Autowiredprivate DataSource dataSource;@Autowiredprivate RedisConnectionFactory connectionFactory;@Autowiredprivate MyOAuth2WebResponseExceptionTranslator webResponseExceptionTranslator;@Beanpublic TokenStore tokenStore() {// token 相关信息保存在 redis 中return new RedisTokenStore( connectionFactory );}@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()").allowFormAuthenticationForClients();}@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {// 客户端信息保存在数据库中:表 oauth_client_details// 如果oauth_client_details表中将autoApprove设置为true,// 这样我们就不会重定向和提升为手动批准任何范围clients.jdbc(dataSource);}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {//开启密码授权类型endpoints.authenticationManager(authenticationManager);//配置token存储方式endpoints.tokenStore(tokenStore());//自定义登录或者鉴权失败时的返回信息endpoints.exceptionTranslator(webResponseExceptionTranslator);//要使用refresh_token的话,需要额外配置userDetailsServiceendpoints.userDetailsService( userDetailsService );endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);}
}

1.3 资源服务器配置

/*** 资源提供端的配置*/
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {@Autowiredprivate RestAuthAccessDeniedHandler deniedHandler;@Autowiredprivate MyAuthenticationEntryPoint authenticationEntryPoint;/*** 这里设置需要token验证的url* 可以在WebSecurityConfigurerAdapter中排除掉,* 对于相同的url,如果二者都配置了验证* 则优先进入ResourceServerConfigurerAdapter,进行token验证。而不会进行* WebSecurityConfigurerAdapter 的 basic auth或表单认证。*/@Overridepublic void configure(HttpSecurity http) throws Exception {http.requestMatchers().antMatchers("/user/me").and().authorizeRequests().antMatchers("/user/me").authenticated();//需要的时候创建session,支持从session中获取认证信息,ResourceServerConfiguration中//session创建策略是stateless不使用,这里其覆盖配置可创建sessionhttp.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);}@Overridepublic void configure(ResourceServerSecurityConfigurer resources) {resources.authenticationEntryPoint(authenticationEntryPoint).accessDeniedHandler(deniedHandler);//此处是关键,默认stateless=true,只支持access_token形式,// OAuth2客户端连接需要使用session,所以需要设置成false以支持session授权resources.stateless(false);}
}

1.4 安全配置

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class BrowerSecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate SecurityAuthenticationProvider provider;/*** 如若需从数据库动态判断权限则实现 AccessDecisionManager* @param http* @throws Exception*/@Overrideprotected void configure(HttpSecurity http) throws Exception {http.antMatcher("/**").authorizeRequests().antMatchers("/login", "/oauth/authorize**").permitAll().anyRequest().authenticated().and().formLogin().loginPage("/login").failureUrl("/login?error=true").permitAll().and().logout().invalidateHttpSession(true).clearAuthentication(true).logoutUrl("/logout").and()//配置没有权限的自定义处理类.exceptionHandling().accessDeniedPage("/403"); // 处理异常,拒绝访问就重定向到 403 页面// 设置跨域问题http.cors().and().csrf().disable();http.sessionManagement().invalidSessionUrl("/login");//单用户登录,如果有一个登录了,同一个用户在其他地方不能登录http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true);}@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers("/assets/**");}/*** 自定义验证逻辑* @param auth* @throws Exception*/@Overrideprotected void configure(AuthenticationManagerBuilder auth){auth.authenticationProvider(provider);}@Override@Beanpublic AuthenticationManager authenticationManagerBean() throws Exception{return super.authenticationManager();}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}}

2 客户端应用配置(oauth2-client)

2.1 maven相关依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency><groupId>org.springframework.security.oauth.boot</groupId><artifactId>spring-security-oauth2-autoconfigure</artifactId><version>2.0.1.RELEASE</version>
</dependency>

2.2安全配置

@Configuration
@EnableOAuth2Sso
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate RestAuthAccessDeniedHandler deniedHandler;@Overridepublic void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated().and().logout().invalidateHttpSession(true).clearAuthentication(true).logoutSuccessUrl("http://localhost:8081/auth/logout").and()//配置没有权限的自定义处理类.exceptionHandling().accessDeniedHandler(deniedHandler);http.csrf().disable();// security 不开启 登录验证http.httpBasic().disable();}
}

2.3 application.yml配置

server:port: 8082servlet:context-path: /uisession:cookie:name: UISESSIONsecurity:oauth2:client:clientId: devclientSecret: 11accessTokenUri: http://localhost:8081/auth/oauth/tokenuserAuthorizationUri: http://localhost:8081/auth/oauth/authorizeresource:userInfoUri: http://localhost:8081/auth/user/me

注意事项

  • 禁用了默认的基本身份验证
  • accessTokenUri是获取访问令牌的URI
  • userAuthorizationUri是将用户重定向到的授权URI
  • userInfoUri 用户端点的URI,以获取当前用户详细信息

实现效果预览

https://www.zhihu.com/video/1187755860582014976

代码地址

https://github.com/ltztao/spring-security-oauth2-server

https://github.com/ltztao/spring-boot-oauth2-client

参考文章

https://www.baeldung.com/sso-spring-security-oauth2

oauth2 单点登录_Spring Security Oauth2和Spring Boot实现单点登录相关推荐

  1. Spring Security OAuth2.0_总结_Spring Security OAuth2.0认证授权---springcloud工作笔记157

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 开通了个人技术微信公众号:credream,有需要的朋友可以添加相互学习

  2. OAuth2.0_介绍_Spring Security OAuth2.0认证授权---springcloud工作笔记137

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 上面是oauth2.0的一些介绍. 我们说一下oauth2.0的一个验证的过程, oauth2.0 ...

  3. springsecurity 不允许session并行登录_Spring Security 实战干货:实现自定义退出登录...

    我是 码农小胖哥.天天有编程干货分享.觉得写的不错.点个赞,转发一下,关注一下.本文为个人原创文章,转载请注明出处,非法转载抄袭将追究其责任. 1. 前言 上一篇对 Spring Security 所 ...

  4. Spring Boot集成第三方登录之微信登录

    Spring Boot集成第三方登录之微信登录 准备工作 注册 创建网站应用 网站应用开发指南 授权流程 请求CODE 获取access_token 使用access_token调用接口 获取用户个人 ...

  5. Spring Boot集成第三方登录之微博登录

    Spring Boot集成第三方登录之微博登录 准备工作 网站接入 开发者信息认证 创建应用 流程分析 引导授权用户 用户授权 授权成功 换取Access Token HTTP客户端 使用Access ...

  6. logback redis_使用Spring Boot和Logback登录到Redis

    logback redis 在进行集中式日志记录时,例如使用Elasticsearch,Logstash和Kibana或Graylog2,您可以为Java应用程序提供多个选项. 您既可以编写标准的应用 ...

  7. 使用Spring Boot和Logback登录到Redis

    在进行集中式日志记录时,例如使用Elasticsearch,Logstash和Kibana或Graylog2,您可以为Java应用程序提供几个选项. 您既可以编写标准的应用程序日志,也可以使用Logs ...

  8. Spring Boot 入门之登录创建

    Spring Boot 入门之登录创建 一.在IDEA中创建一个springboot项目 1.使用Spring Initializr创建项目 2.选定Developer Tools中的Spring B ...

  9. java 授权码模式_Spring Security OAuth2 授权码模式的实现

    写在前边 在文章OAuth 2.0 概念及授权流程梳理 中我们谈到OAuth 2.0的概念与流程,这里我准备分别记一记这几种授权模式的demo,一方面为自己的最近的学习做个总结,另一方面做下知识输出, ...

最新文章

  1. 区别:电感、磁珠和零欧电阻的作用
  2. PHP 使用 AES/ECB/PKCS7 padding 加密
  3. Python实现——二元线性回归(最小二乘法)
  4. oracle 执行计划 ppt,oracle查看执行计划的方法
  5. 关于HTTP协议的几个问题
  6. L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到一个处理错误...
  7. 免费mysql_MySql 所有的版本都是免费的吗?
  8. OOP的核心思想是什么?
  9. 大乱斗ps4好玩吗_飞刀剑影乱作战:飞刀大乱斗ol游戏小程序,点开既玩
  10. 计算机网络数据传输率的基本单位是,计算机网络中,数据的传输速度常用的单位是什么...
  11. bingo update1
  12. Oracle EXPLAIN PLAN用法
  13. 【Paper】2022_Adaptive Formation Control of Unmanned Underwater Vehicles with Collision Avoidance unde
  14. 拒酒词,好难找哟,留到有用
  15. 第三章 CSS 选择器的命名
  16. 读史有感(写于07年冬)
  17. 在centos7中下载搜狗输入法
  18. 窥探现代浏览器架构(二)
  19. form layui 同时提交多个对象_layui实现form表单同时提交数据和文件的代码
  20. OKhttp 拦截器Intercept token失效验证

热门文章

  1. mysql一个索引占用G_mysql 索引 使用注意细节
  2. python全栈开发 * 表格标签 表单标签 css 引入方式 * 180807
  3. 高并发高可用系统应对策略的一些思考
  4. MongoDB之bson的介绍
  5. 201621123028《Java程序设计》第一周学习总结
  6. python 数据的读取
  7. 读书印记 - 《清醒:如何用价值观创造价值》
  8. SQL Server基础
  9. Error:Execution failed for task ':myapp:dexDebug'. com.android.ide.common.process.ProcessExcepti
  10. PHP生成PDF完美支持中文,解决TCPDF乱码