oauth2 单点登录_Spring Security Oauth2和Spring Boot实现单点登录
最近在学习单点登录相关,调查了一下目前流行的单点登录解决方案: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实现单点登录相关推荐
- Spring Security OAuth2.0_总结_Spring Security OAuth2.0认证授权---springcloud工作笔记157
技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 开通了个人技术微信公众号:credream,有需要的朋友可以添加相互学习
- OAuth2.0_介绍_Spring Security OAuth2.0认证授权---springcloud工作笔记137
技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 上面是oauth2.0的一些介绍. 我们说一下oauth2.0的一个验证的过程, oauth2.0 ...
- springsecurity 不允许session并行登录_Spring Security 实战干货:实现自定义退出登录...
我是 码农小胖哥.天天有编程干货分享.觉得写的不错.点个赞,转发一下,关注一下.本文为个人原创文章,转载请注明出处,非法转载抄袭将追究其责任. 1. 前言 上一篇对 Spring Security 所 ...
- Spring Boot集成第三方登录之微信登录
Spring Boot集成第三方登录之微信登录 准备工作 注册 创建网站应用 网站应用开发指南 授权流程 请求CODE 获取access_token 使用access_token调用接口 获取用户个人 ...
- Spring Boot集成第三方登录之微博登录
Spring Boot集成第三方登录之微博登录 准备工作 网站接入 开发者信息认证 创建应用 流程分析 引导授权用户 用户授权 授权成功 换取Access Token HTTP客户端 使用Access ...
- logback redis_使用Spring Boot和Logback登录到Redis
logback redis 在进行集中式日志记录时,例如使用Elasticsearch,Logstash和Kibana或Graylog2,您可以为Java应用程序提供多个选项. 您既可以编写标准的应用 ...
- 使用Spring Boot和Logback登录到Redis
在进行集中式日志记录时,例如使用Elasticsearch,Logstash和Kibana或Graylog2,您可以为Java应用程序提供几个选项. 您既可以编写标准的应用程序日志,也可以使用Logs ...
- Spring Boot 入门之登录创建
Spring Boot 入门之登录创建 一.在IDEA中创建一个springboot项目 1.使用Spring Initializr创建项目 2.选定Developer Tools中的Spring B ...
- java 授权码模式_Spring Security OAuth2 授权码模式的实现
写在前边 在文章OAuth 2.0 概念及授权流程梳理 中我们谈到OAuth 2.0的概念与流程,这里我准备分别记一记这几种授权模式的demo,一方面为自己的最近的学习做个总结,另一方面做下知识输出, ...
最新文章
- 区别:电感、磁珠和零欧电阻的作用
- PHP 使用 AES/ECB/PKCS7 padding 加密
- Python实现——二元线性回归(最小二乘法)
- oracle 执行计划 ppt,oracle查看执行计划的方法
- 关于HTTP协议的几个问题
- L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到一个处理错误...
- 免费mysql_MySql 所有的版本都是免费的吗?
- OOP的核心思想是什么?
- 大乱斗ps4好玩吗_飞刀剑影乱作战:飞刀大乱斗ol游戏小程序,点开既玩
- 计算机网络数据传输率的基本单位是,计算机网络中,数据的传输速度常用的单位是什么...
- bingo update1
- Oracle EXPLAIN PLAN用法
- 【Paper】2022_Adaptive Formation Control of Unmanned Underwater Vehicles with Collision Avoidance unde
- 拒酒词,好难找哟,留到有用
- 第三章 CSS 选择器的命名
- 读史有感(写于07年冬)
- 在centos7中下载搜狗输入法
- 窥探现代浏览器架构(二)
- form layui 同时提交多个对象_layui实现form表单同时提交数据和文件的代码
- OKhttp 拦截器Intercept token失效验证
热门文章
- mysql一个索引占用G_mysql 索引 使用注意细节
- python全栈开发 * 表格标签 表单标签 css 引入方式 * 180807
- 高并发高可用系统应对策略的一些思考
- MongoDB之bson的介绍
- 201621123028《Java程序设计》第一周学习总结
- python 数据的读取
- 读书印记 - 《清醒:如何用价值观创造价值》
- SQL Server基础
- Error:Execution failed for task ':myapp:dexDebug'. com.android.ide.common.process.ProcessExcepti
- PHP生成PDF完美支持中文,解决TCPDF乱码