# spring-oauth2.0 **Repository Path**: szile/spring-oauth2.0 ## Basic Information - **Project Name**: spring-oauth2.0 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-09-22 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## Spring Security OAuth2.0认证授权 来自黑马程序员的[java进阶教程2天快速入门Spring Security OAuth2.0认证授权-哔哩哔哩](https://www.bilibili.com/video/BV1VE411h7aL)-学习笔记 ##### 4.4.2 会话控制 我们可以通过以下选项准确控制会话何时创建以及SpringSecurity如何与之交互: | 机制 | 描述 | | ---------- | ------------------------------------------------------------ | | always | 如果没有session存在就创建一个 | | ifRequired | 如果需要就创建一个Session(默认)登录时 | | never | SpringSecurity将不会创建Session,但是如果应用中其他地方创建了Session,那么SpringSecurity将会使用它 | | stateless | SpringSecurity将绝对不会创建Session,也不使用Session | ###### 会话超时 可以再sevlet容器中设置Session的超时时间,如果设置Session有效期为3600s; spring boot 配置文件: ```properties server.servlet.session.timeout=3600s ``` session超时之后,可以通过Spring Security设置跳转的路径。 ```java http.sessionManagement() .expiredUrl("/login-view?error=EXPIRED_SESSION") .invalidSessionUrl("/login-view?error=INVALID_SESSION"); ``` expired指session过期,invalidSession指传入的sessionid无效。 ###### 安全会话cookie 我们可以使用httpOnly和secure标签来保护我们的会话cookie: - **httpOnly**:如果为true,那么浏览器脚本将无法访问cookie - **secure**:如果为true,则cookie将仅通过HTTPS链接发送 ```properties server.servlet.session.cookie.http-only=true server.servlet.session.cookie.secure=true ``` #### 退出 **注意:如果让logout在GET请求下生效,必须关闭防止CSRF攻击csrf().disable()。如果开启了CSRF,必须使用post方式请求/logout** ##### logoutHandler 一般来说,LogoutHandler的实现类被用来执行必要的清理,因而他们不应该抛出异常。 下面是Spring Security提供的一些实现: - PersistentTokenBasedRememberMeServices基于持久化token的RememberMe功能的相关清理 - TokenBasedRememberMeService基于token的RememberMe功能的相关清理 - CookieClearingLogoutHandler退出时Cookie的相关清理 - CsrfLogoutHandler 负责在退出时移除csrfToken - SecurityContextLogoutHandler退出时SecurityContext的相关清理 链式API提供了调用相应的`LogoutHandler`实现的快捷方式,比如deleteCookies(). ### 4.7 授权 尽量使用基于权限(资源)的授权方式 ##### 4.7.2 web 授权 保护URL常用的方法有: - **authenticated()**保护URL,需要用户登录 - **permitAll()**指定URL无需保护,一般应用与静态资源文件 - **hasRole(String role)**限制单个角色访问,角色被增加“ROLE_",所以”ADMIN"将和“ROLE_ADMIN”进行比较 - **hasAuthority(String authority)**限制单个权限访问 - **hasAnyRole(String... roles)**允许多个角色访问 - **hasAuthority(String... authorities)**允许多个权限访问 - **access(String attribute)**该方法使用SpEL表达式,所以可以创建复杂的限制 - **hasIpAddress(String ipAddressExpression)**限制IP地址或子网 ##### 注意: 规则的顺序是重要的,更具体的规则应该先写。 ##### 4.7.3 方法授权 从Spring Security2.0版本开始,它支持服务层方法的安全性的支持。 @PreAuthorize, @PostAuthorize, @Secured 三类注解 使用 `@EnableGlobalMethodSecurity`注解来启动基于注解的安全性。 #### httpSecurity配置列表 | 方法 | 说明 | | ------------------- | ------------------------------------------------------------ | | openidLogin() | 用于基于OpenId的验证 | | headers() | 将安全标头添加到响应 | | cors() | 配置跨域资源共享(CORS) | | sessionManagement() | 允许配置会话管理 | | portMapper() | 允许配置一个PortMapper(HttpSecurity#getSharedObject(calss)),其他提供SecurityConfigurer的对象使用PortMapper从HTTP重定向到HTTPS或者从HTTPS重定向到HTTP。默认情况下,Spring Security使用一个PortMapperImpl映射HTTP端口8080到HTTPS端口8443,HTTP端口80到HTTPS端口443 | | jee() | 配置基于容器的预认证。在这种情况下,认证由Servlet容器管理 | | x509() | 配置基于x509的认证 | | rememberMe() | 允许配置“记住我”的验证 | | authorizeRequests() | 允许基于使用HttpServletRequest限制访问 | | requestCache() | 允许配置请求缓存 | | exceptionHanding() | 允许配置错误处理 | | securityContext() | 在HttpServletRequests之间的SecurityContextHoldler上设置SecurityContext的管理。当使用WebSecurityConfigurerAdapter时,这将自动应用 | | servletApi() | 将HttpServletRequest方法与在其上找到的值集成到SecurityContext中。当使用WebSecurityConfigurerAdapter时,这将自动应用 | | csrf() | 添加csrf支持,使用WebSecurityConfigurerAdapter时,默认启用 | | logout() | 添加退出登录支持。当使用WebSecurityConfigurerAdapter时,这将自动应用。默认情况是,访问“/logout”,使Http Session无效来清除用户,清除已配置的任何#rememberMe()身份验证,清除SecurityContextHolder,然后重定向到“/login?success" | | anonymous() | 允许配置匿名用户的表示方法。当与WebSecurityConfigurerAdapter结合使用时,这将自动应用。默认情况下,匿名用户将使用org.springframework.security.authenticatin.AnonymousAuthenticationToken表示,并包含角色”ROLE_ANONYMOUS" | | formLogin() | 指定支持基于表单的身份验证。如果未指定FormLoginConfigurer#loginPage(String),则将生成默认登录页面 | | oath2Login() | 根据外部OAuth2.0或OpenID Connect 1.0 提供程序配置身份验证 | | requiresChannel() | 配置通道安全。为了使该配置有用,必须提供至少一个到所需信道的映射 | | httpBasic() | 配置HttpBasic验证 | | addFilterAt() | 在指定的Filter类的位置添加过滤器 | ## 5. 分布式系统认证方案 ### 5.1 什么是分布式系统 分布式系统基本特性: 1. 分布行:每个部分都可以独立部署,服务之间交互通过网络进行通信 2. 伸缩性:每个部分都可以集群方式部署,并可针对部分结点进行硬件及软件扩容,具有一定的伸缩能力。 3. 共享性:每个部分都可以作为共享资源对外提供服务,多部分可能有操作共享资源的情况 4. 开放性:每个部分根据需求都可以对外发布共享资源的访问接口,并可以允许第三方系统访问 ### 5.2 分布式认证需求 #### 统一认证授权 ​ 提供独立的认证服务,同意处理认证授权。 ​ 认证方式必须可扩展,支持各种认证需求,比如:用户名密码认证,短信验证码,二维码,人脸识别等认证方式,并可以灵活切换。 #### 应用接入认证 ### 5.3 分布式认证方案 ## 6. OAuth2.0 ### 6.1 OAuth2.0 介绍 OAuth(开发协议)是一个开放标准,允许用户授权第三方应用访问用户存储在另外的服务提供者上的喜喜,而不需要将用户名和密码提供给第三方应用或分享他们数据的所有内容。 ### 6.2 Spring Cloud Security OAuth2 #### 6.2.1 环境介绍 OAuth2.0 服务提供方涵盖两个服务,即授权服务(Authorization Server, 也叫认证服务)和资源服务(Resource Server) **授权服务(Authorization Server)**应包含接入端以及登入用户的合法性及逆行验证并颁发token等功能,对令牌的请求端点由SpringMVC控制器进行实现,下面是配置一个认证服务器必须实现的endpoints: - **AuthorizationEndpoint**服务于认证请求。默认url: /oauth/authorize - **TokenEndpoint**服务于访问令牌的请求。默认url: /oauth/token **资源服务(Resource Server)**应包含对资源的保护功能,对非法请求进行拦截,对请求中的token进行解析鉴权等,下面的过滤器用于实现OAuth2.0资源服务; - OAuth2AuthenticationProcessingFilter用来对请求给出的身份令牌解析鉴权。 #### 配置授权服务 需要配置下面三个配置: - **ClientDetailServiceConfigurer**:用来配置客户端详情服务(ClientDetailService),客户端详情信息在这里进行初始化,你能够把客户端详情信息写死在这里或通过数据库来存储调取详情信息。 - **AuthorizationServerEndpointsConfigurer**:用来配置令牌(token)的访问端点和令牌服务(token services). - **AuthorizationServerSecurityCOnfigurer**:用来配置令牌端点的安全约束。 ```java public class AuthorizationServerConfigurerAdapter implements AuthorizationServerConfigurer { public AuthorizationServerConfigurerAdapter() { } /** * 授权安全约束配置 */ public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { } /** * 客户端详情服务配置 */ public void configure(ClientDetailsServiceConfigurer clients) throws Exception { } /** * 配置授权服务端点 */ public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { } } ``` ##### 6.2.2.3 令牌访问端点配置 AuthorizationServerEndpointsConfigurer这个对象的实例可以完成令牌服务以及令牌endpoint配置。 ###### 配置授权类型(Grant Types) AuthorizationServerEndpointsConfigurer支持的**授权类型(Grant Types)**: - authenticationManager:认证管理器,当选择资源所有者密码()授权类型的时候,请注入一个authenticationManager对象 - userDetailsService: - AuthorizationCodeServices:用来设置授权码服务的,主要用于”authorization_code"授权码类型模式。 - implicitGrantService:设置隐式授权模式。 - tokenGrantService: ###### 配置授权端点的url AuthorizationServerEndpointsConfigurer这个配置对象有一个叫做pathMapping()方法用来配置端点URL链接,它有两个参数: - 第一个:String类型,这个端点URL的默认链接 - 第二个:String类型,你要进行代替的URL链接 以上的参数都将以“/”字符为开始的字符串,框架默认URL链接如下列表,可以作为pathMapping()方法的第一个参数: - /oauth/authorize:授权端点 - /oauth/token:令牌端点 - /oauth/confirm_access:用户确认授权提交端点 - /oauth/error:授权服务错误信息端点 - /oauth/check_token:用于资源服务访问的令牌解析端点 - /oauth/token_key:提供公有密钥的端点,如果使用JWT令牌的话。 需要注意的是授权端点这个URL应该被Spring Security保护起来只供授权用户访问。 远程校验令牌存在的问题: 当访问量非常大使,认证服务器的压力非常大, ## 6.3 JWT令牌 **1. 什么是JWT?** JSON web token (JWT) 是一种开放标准 ###### JWT令牌的优点 1. jwt基于json,非常方便解析 2. 可以在令牌中自定义丰富的内容,易扩展 3. 通过非对称加密算法及数字签名技术,JWT防止篡改,安全性高 4. 资源服务使用JWT可不依靠认证服务即可完成授权 ###### 缺点: 1. JWT令牌较长,占存储空间较大。 **2. WT令牌结构** JWT令牌由三部分组成,每部分中间使用(.)分隔。 - **Header** 头 包含令牌类型及算法 - **Payload** 负载 包含有效信息 - **Signature** 签名