简化模式
有些纯前端应用,必须将令牌储存在前端。那么可以使用简化模式(隐藏式)来申请授权,颁发令牌。
- 浏览器向授权服务器申请授权,并设置response_type=token,表示直接返回令牌
- 授权服务器通过校验后跳转到重定向地址并返回token
- 浏览器通过token去申请资源
这种方式把令牌直接传给前端是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短,通常
浏览器关掉,令牌就失效了。
代码实战
第一步,创建maven项目implicit_server,pom文件如下所示
<parent>
<artifactId>microservice-parent</artifactId>
<groupId>com.curise.microservice</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>implicit_server</artifactId>
<description>OAuth2.0简化模式</description>
<dependencies>
<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>
<!-- for OAuth 2.0 -->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
第二步,创建授权服务器,这里设置了简化模式令牌有效时间120s
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
// 客户端id
.withClient("app")
// 客户端密钥
.secret("123")
// 权限
.scopes("read","write")
// 获取授权码后重定向地址
.redirectUris("http://localhost:9000/callback")
// 授权码和刷新token
.authorizedGrantTypes("authorization_code","refresh_token")
.and()
.withClient("app1")
.secret("1234")
.scopes("read", "write")
// 密码模式和刷新token
.authorizedGrantTypes("password", "refresh_token")
.and()
.withClient("app2")
.secret("1234")
.scopes("read", "write")
.redirectUris("http://localhost:9000/callback")
// 令牌有效时间120s
.accessTokenValiditySeconds(120)
// 简化模式
.authorizedGrantTypes("implicit");
}
}
第三步,创建资源服务器
@Configuration
@EnableResourceServer
public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.requestMatchers()
// /api/**请求需要OAuth鉴权
.antMatchers("/api/**");
}
}
第四步,创建配置文件
server.port=8080
security.user.name=root
security.user.password=root
第五步,创建Controller输出资源
@RestController
public class UserController {
@GetMapping("/api/userInfo")
public ResponseEntity<UserInfo> getUserInfo(){
User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String email = user.getUsername() + "@qq.com";
UserInfo userInfo = new UserInfo();
userInfo.setUsername(user.getUsername());
userInfo.setEmail(email);
return ResponseEntity.ok(userInfo);
}
}
第六步,启动服务
第七步,浏览器发送请求获取令牌
client_id:客户端id
redirect_uri:申请授权后重定向地址(这里是随便写的)
response_type:设置返回token
scope:设置权限是read
授权后调整的url如图所示
第八步,通过令牌获取用户信息
代码已经共享到GitHub,地址:https://github.com/WYA1993/microservice