梦入琼楼寒有月,行过石树冻无烟

Spring Security OAuth

开放授权(Open Authorization)是一种开放的协议,即地桑房可以使用第三方应用代表资源所有者获取有限的访问授权机制,在整个授权的过程中,第三方站点无需涉及用户的密码即可获取部分的资源。在很多的站点场景之中,都提供了第三方登入等相关信息,如QQ、微信扫码登录等机制,而这当我们点击第三方登录时会跳转到授权的登录页面,然后登入成功就会跳转到访问的目标站点之中,而这过程中该站点就不会获取到用户的密码等相关信息,主要流程如下:

  1. 客户端要求用户提供授权许可
  2. 用户同意向客户端提供授权许可
  3. 客户端携带用户所提供的授权许可向授权服务器申请访问令牌
  4. 授权服务器验证客户端是否携带授权许可,如有效则发放访问令牌
  5. 客户端使用访问令牌申请服务器资源
  6. 资源服务器验证访问令牌,确认正确后向客户端提供资源。

四种授权模式

授权码模式(Authorization Code)

授权码模式是功能较为完整,安全性和用户信息存在应用服务器宝楼风险小、服务器与服务器之间的访问难以被抓取等相关优点。

  1. 重定向到认证服务器

  2. 认证服务器用户授权

  3. 认证服务器->应用服务器重定向应用服务器,带上授权码

  4. 应用服务器->认证服务器获取访问令牌(用授权码换得)

  5. 认证服务器->应用服务器认证服务器获取访问令牌

  6. 应用服务器->资源服务器访问资源服务器

隐式授权(Implicit Grant)

隐式授权模式是指访问令牌通过重定向的方式传递到用户浏览器之中,之后通过js获取访问令牌。通过使用隐士验证我们可以免于后台和存储,将信息存储与Token或Cookie之中,基本上通过认证后可直接进行访问。

密码授权模式(Password Credentials)

密码授权模式即通过浏览器直接携带用户的密码向授权服务器申请令牌,这种授权模式不用通过跳转到授权服务器进行,而是通过资源服务器提供的页面进行。

客户端授权模式(Client Credentials)

与上面三种模式相比之下,客户端授权模式相对于较为简单,只需要客户端请应用公钥、密钥等洗脑洗想授权服务器申请访问令牌,从而货渠道服务器所提供的资源。

OAuth 2.0 github and login

如果要接入github的授权,则需要访问https://github.com/settings/applications/new,来申请一个应用并在此填写应用名称、主页URL、应用说明、认证时重定向的页面即可。(需要注意的是在本地开发的时候,主页URL需要设置为```http://localhost:8080```,认证重定向地址设置为```http://localhost:8080/login/oauth2/code/github```)。
点击确定后将会跳转至应用创建成功页面,并获得到客户端ID(Client ID)以及客户端密码(Client secrets)

Client ID
****cd6dcb6f7289b5c56
****2a5b45fa0b528837b2181617e7

Spring Security OAuth默认的重定向模板是{baseUrl}/login/oauth2/code{registrationId}registrationId是Client Registrationa的唯一ID,通常接入的OAuth服务提供商的简称来命名。

resources

application.yml

1
2
3
4
5
6
7
8
9
10
spring:
security:
oauth2:
client:
registration:
github:
clientId: <clientid>
clientSecret: <clientSecret>
# 需要获取的信息
scope: read:user, user:email

static

login.html

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Spring boot security and OAuth2.0 github login</title>
</head>
<body>
<h1>Login github> </h1><a href="/oauth2/authorization/github">Go</a>
</body>
</html>

Controller

IndexController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.example.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.security.Principal;

@RestController
class IndexController {
@Autowired
private OAuth2AuthorizedClientService auth2AuthorizedClientService;

@GetMapping(value = "/")
public String index(Principal principal) {
return "Hey," + principal.getName(); // getName 为获取其github id
}
}

Configuration

WebSecurityConfiguration.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.example.demo.configuration;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2Login()
.loginPage("/login.html")
.defaultSuccessUrl("/").permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout","GET"))
.deleteCookies("true")
.logoutSuccessUrl("/login.html?logout")
.permitAll();
}
}
⬅️ Go back