不是客户端,而是服务端。
版本:
Spring Boot 1.4.3、Spring Security OAuth2 2.0.12
OAuth2.0的开源 Server / Client 实现可以参考这里:
https://oauth.net/code/,这里采用Spring Security OAuth2实现四种授权模式中最常用的:Authorization Code Grant。
具体可以看OAuth2.0标准的定义:
https://tools.ietf.org/html/rfc6749#section-4.1。
这里首先只为演示 OAuth2.0 的整个过程,做最小实现!
Spring Security OAuth2默认提供的四个URL:
- /oauth/authorize : 授权AuthorizationEndpoint
- /oauth/token : 令牌TokenEndpoint
- /oauth/check_token : 令牌校验CheckTokenEndpoint
- /oauth/confirm_access : 授权页面WhitelabelApprovalEndpoint
- /oauth/error : 错误页面WhitelabelErrorEndpoint
相关文章:
Spring Security OAuth2 Provider 之 最小实现
Spring Security OAuth2 Provider 之 数据库存储
Spring Security OAuth2 Provider 之 第三方登录简单演示
Spring Security OAuth2 Provider 之 自定义开发
Spring Security OAuth2 Provider 之 整合JWT
代码如下:
pom.xml
<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</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
Application.java
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Config.java
public class Config {
public static final String OAUTH_CLIENT_ID = "oauth_client";
public static final String OAUTH_CLIENT_SECRET = "oauth_client_secret";
public static final String RESOURCE_ID = "my_resource_id";
public static final String[] SCOPES = { "read", "write" };
@Configuration
@EnableAuthorizationServer
static class OAuthAuthorizationConfig extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient(OAUTH_CLIENT_ID)
.secret(OAUTH_CLIENT_SECRET)
.resourceIds(RESOURCE_ID)
.scopes(SCOPES)
.authorities("ROLE_USER")
.authorizedGrantTypes("authorization_code", "refresh_token")
.redirectUris("http://default-oauth-callback.com")
.accessTokenValiditySeconds(60*30) // 30min
.refreshTokenValiditySeconds(60*60*24); // 24h
}
}
@Configuration
@EnableResourceServer
static class OAuthResourceConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(HttpMethod.GET, "/api/**").access("#oauth2.hasScope('read')")
.antMatchers(HttpMethod.POST, "/api/**").access("#oauth2.hasScope('write')");
}
}
@Configuration
@EnableWebSecurity
static class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("123").roles("USER")
.and()
.withUser("admin").password("123").roles("ADMIN");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/oauth/authorize").authenticated()
.and()
.httpBasic().realmName("OAuth Server");
}
}
}
Controller.java
@RestController
public class Controller {
@GetMapping("/api/get")
public String get() {
return "Hello World!";
}
@PostMapping("/api/post")
public String post() {
return "POST process has finished.";
}
@GetMapping("/api/user")
public Object get(HttpServletRequest req) {
SecurityContextImpl sci = (SecurityContextImpl) req.getSession().getAttribute("SPRING_SECURITY_CONTEXT");
if (sci != null) {
Authentication authentication = sci.getAuthentication();
if (authentication != null) {
return authentication.getPrincipal();
}
}
return "none";
}
}
Test.java
public class Test {
public static void main(String[] args) {
System.out.println(generate("oauth_client", "oauth_client_secret"));
}
private static String generate(String clientId, String clientSecret) {
String creds = String.format("%s:%s", new Object[] { clientId, clientSecret });
try {
return "Basic " + new String(Base64.encode(creds.getBytes("UTF-8")));
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("Could not convert String");
}
}
}
【Run As】【Spring Boot App】启动服务器后,看到以下Log:
引用
Mapped "{[/oauth/authorize]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(java.util.Map<java.lang.String, java.lang.Object>,java.util.Map<java.lang.String, java.lang.String>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)
Mapped "{[/oauth/authorize],methods=[POST],params=[user_oauth_approval]}" onto public org.springframework.web.servlet.View org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.approveOrDeny(java.util.Map<java.lang.String, java.lang.String>,java.util.Map<java.lang.String, ?>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)
Mapped "{[/oauth/token],methods=[POST]}" onto public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException
Mapped "{[/oauth/token],methods=[GET]}" onto public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.getAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException
Mapped "{[/oauth/check_token]}" onto public java.util.Map<java.lang.String, ?> org.springframework.security.oauth2.provider.endpoint.CheckTokenEndpoint.checkToken(java.lang.String)
Mapped "{[/oauth/confirm_access]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint.getAccessConfirmation(java.util.Map<java.lang.String, java.lang.Object>,javax.servlet.http.HttpServletRequest) throws java.lang.Exception
Mapped "{[/oauth/error]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.WhitelabelErrorEndpoint.handleError(javax.servlet.http.HttpServletRequest)
(1)授权请求(Get)
URL:
http://localhost:8080/oauth/authorize?client_id=oauth_client&scope=read&response_type=code&state=rensanning&redirect_uri=http://default-oauth-callback.com
由于对/oauth/authorize开启了HTTP Basic认证,所以需要输入密码:
输入正确用户名密码(user/123)后显示授权页:
选择Approve点击Authorize按钮后,自动跳转到
http://default-oauth-callback.com?code=sdb6vF&state=rensanning
URL中的code参数值即为授权码,该值是一个6位英数字的随机数,具体可以看源码:org.springframework.security.oauth2.common.util.RandomValueStringGenerator.generate()
!!授权码10分钟过期目前还没有实现!! https://github.com/spring-projects/spring-security-oauth/issues/725
(2)获得令牌(Post)
URL:
http://localhost:8080/oauth/token?grant_type=authorization_code&redirect_uri=http://default-oauth-callback.com&code=sdb6vF
【/oauth/token】默认采用的是HTTP Basic Auth(org.springframework.security.web.authentication.www.BasicAuthenticationFilter),所以需要在HTTP的header里提供clientId和clientSecret的Base64值。具体可以执行Test.java获取。
Authorization: Basic b2F1dGhfY2xpZW50Om9hdXRoX2NsaWVudF9zZWNyZXQ=
通过以下设置,可以通过参数的形式传递clientId和clientSecret的值。比如:http://localhost:8080/oauth/token?grant_type=authorization_code&redirect_uri=http://default-oauth-callback.com&code=sdb6vF&client_id=oauth_client&client_secret=oauth_client_secret
@Configuration
@EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.allowFormAuthenticationForClients();
}
}
返回令牌信息
引用
{
"access_token": "1cc5ffbd-faac-4d20-afd9-b8531acd248e",
"token_type": "bearer",
"refresh_token": "5b319fed-5600-4ea2-8c4f-61f6e3ea6e41",
"expires_in": 1631,
"scope": "read"
}
生成的令牌是一个UUID,具体可以看源码:org.springframework.security.oauth2.provider.token.DefaultTokenServices.createAccessToken()
(4)访问API(Get)
直接访问API返回401。URL:
http://localhost:8080/api/get
通过access_token参数访问。URL:
http://localhost:8080/api/get?access_token=1cc5ffbd-faac-4d20-afd9-b8531acd248e
通过http header参数访问。URL:
http://localhost:8080/api/get
Authorization: Bearer 1cc5ffbd-faac-4d20-afd9-b8531acd248e
*** @EnableResourceServer 自动增加OAuth2AuthenticationProcessingFilter过滤器
*** !!SpringBoot1.5 @EnableResourceServer和@EnableWebSecurity配置的HttpSecurity有先后顺序的问题,需要特殊设置!!参考:
https://github.com/spring-projects/spring-security-oauth/issues/993#issuecomment-284430752
https://stackoverflow.com/questions/29893602/spring-security-form-logging-and-outh2-in-same-app
(5)刷新令牌(Post)
URL:
http://localhost:8080/oauth/token?grant_type=refresh_token&refresh_token=5b319fed-5600-4ea2-8c4f-61f6e3ea6e41
Authorization: Basic b2F1dGhfY2xpZW50Om9hdXRoX2NsaWVudF9zZWNyZXQ=
返回新的access_token:
引用
{
"access_token": "3cbe70fc-753f-44ff-9bb4-0ba6bc3c9aab",
"token_type": "bearer",
"refresh_token": "5b319fed-5600-4ea2-8c4f-61f6e3ea6e41",
"expires_in": 1800,
"scope": "read"
}
旧的Token就不能再用了:
通过新的Token访问API:
同理,可以测试scope为write的权限!
参考:
http://projects.spring.io/spring-security-oauth/docs/oauth2.html
https://segmentfault.com/a/1190000010540911
http://ifeve.com/oauth2-tutorial-all/
http://websystique.com/spring-security/secure-spring-rest-api-using-oauth2/
http://qiita.com/TakahikoKawasaki/items/200951e5b5929f840a1f
https://murashun.jp/blog/20150920-01.html
- 大小: 5.1 KB
- 大小: 7.2 KB
- 大小: 8.4 KB
- 大小: 85.3 KB
- 大小: 72.1 KB
- 大小: 69.8 KB
- 大小: 73.4 KB
- 大小: 82.8 KB
- 大小: 75.7 KB
- 大小: 70.5 KB
- 大小: 136.8 KB
分享到:
相关推荐
总结起来,通过Spring Security OAuth2 Provider 实现第三方登录,主要涉及配置OAuth2的提供者、客户端和资源服务器,以及理解OAuth2的核心概念和流程。这包括设置授权和令牌端点、处理用户认证、请求和验证Access ...
在Spring Boot应用中,通过`spring-boot-starter-data-redis`依赖和`spring.security.oauth2.provider.token.store.redis`配置,可以轻松地将TokenStore切换到Redis。此外,还需要配置Redis连接参数,如主机名、端口...
《Spring Security + OAuth2 + JWT 实现Web安全认证》 在现代Web开发中,安全认证是不可或缺的一部分。Spring Security作为Java领域中强大的安全框架,配合OAuth2和JWT(JSON Web Token),可以构建出高效且安全的...
当我们谈论"springboot与security oauth2整合例子",实际上是在讨论如何将OAuth2协议集成到Spring Boot和Spring Security中,以实现基于令牌(Token)的身份验证和授权机制。OAuth2是一种开放标准,用于授权第三方...
本源码工程是针对SpringSecurity3.x的深入学习资源,包含了实现文档对应的源代码,能够帮助开发者更好地理解和运用该框架。 首先,SpringSecurity的核心概念包括认证(Authentication)和授权(Authorization)。...
2. **配置Spring Security**:在Spring Security的配置类中,设置安全策略,例如开启CAS认证,并指定CasAuthenticationFilter和CasAuthenticationEntryPoint。 3. **定义Service Provider**:在CAS服务器上,为...
Spring Security 提供了多种认证方式,如表单登录、HTTP基本认证、OAuth2等。 - **授权**:定义了哪些认证过的用户可以访问哪些资源。Spring Security 使用访问决策管理器(Access Decision Manager)和访问决策...
"springsecurity-namespace"可能指的是Spring Security的XML命名空间配置。在Spring Security的早期版本中,使用XML配置是最常见的实践。例如,你可能会看到以下片段: ```xml **" access="hasRole('ROLE_ADMIN')...
7. **OAuth2 and OpenID Connect Support**:SpringSecurity还支持OAuth2和OpenID Connect协议,这对于构建现代的API和单点登录(SSO)系统非常有用。 在"SpringSecurity权限管理开发手册.pdf"和"SpringSecurity...
**Spring Security新手入门级Maven实例...随着对Spring Security的深入学习,你将能够实现更复杂的场景,如OAuth2集成、记住我功能、CSRF防护、基于URL的访问控制等。不断实践和探索,你将成为Spring Security的专家。
- **OAuth2 Provider**: 使用Spring Security OAuth2模块,我们可以轻松创建一个OAuth2授权服务器。 - **Authorization Code Grant Flow**: OAuth2中最常见的授权类型,用户通过浏览器重定向到授权服务器进行身份...
为了实现这些功能,开发者可能需要配置Spring Security的OAuth2 Resource Server,以处理来自OAuth2 Provider的令牌。同时,还需要设置Authorization Server来处理用户的登录、授权请求,生成访问令牌。这些令牌可以...
Spring Security是Spring框架的一个核心组件,专注于提供全面的安全解决方案,包括认证、授权和访问控制。在Spring Security 4.0.1版本中,这个框架引入了一些重要的改进和更新,以增强其性能和安全性。 首先,...
Spring OAuth2 Login是一个基于Spring Security框架的实现,用于在Web应用程序中集成OAuth2登录功能。这个项目的核心目标是提供一种安全、便捷的方式来让用户通过第三方身份验证服务(如Google、Facebook或GitHub)...
Spring Security 由一堆 Filter 实现,包括 LogoutFilter、UsernamePasswordAuthenticationFilter 等。这些 Filter 负责拦截请求,并将其交由其他组件完成细分的功能。其中,UsernamePasswordAuthenticationFilter ...
Spring Security也支持OAuth2,可以实现第三方登录功能,如Google、Facebook登录。通过OAuth2,Spring Security可以帮助应用保护API,只允许经过授权的客户端访问。 **源码分析** 深入理解Spring Security需要研究...
- **OAuth2集成**: 如何使用Spring Security与OAuth2结合,实现第三方登录功能。 - **CORS支持**: 设置跨域请求的安全策略,允许不同源的Web应用进行交互。 - **国际化的错误处理**: 如何定制Spring Security的...
Spring Security还支持OAuth2,可以与其他服务进行安全交互,如Google、Facebook登录。 ### 8. 实战案例 - **防止CSRF攻击**:Spring Security默认开启CSRF保护,可通过配置禁用或调整策略。 - **RESTful API安全*...
import org.springframework.security.oauth2.provider.userDetailsService; import org.springframework.stereotype.Component; import javax.annotation.Resource; import org.springframework.cache.ehcache....
在“springsecurity-github-login-:OAuth实现”项目中,我们将探讨如何利用Spring Security集成GitHub的OAuth2认证来实现用户登录功能。 OAuth2是一种授权框架,允许第三方应用在用户许可的情况下访问其存储在特定...