先解释一下Oauth2 是什么?
OAuth2 是一个授权代理服务,是一种开放授权协议、其核心就是第三方应用颁发令牌
OAuth2有4种角色
分别为资源拥有者、资源服务、授权服务、客户端第三方应用
OAuth2有4种授权方式,分别为
下面开始是整合Oauth2之授权码案例
创建一个Sprng boot 项目,具体的项目工程结构如下
主要的POM文件内容如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- OAuth 2.0 的核心jar -->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.7.RELEASE</version>
</dependency>
</dependencies>
spring-security-oauth2主要一些如下
AuthorizationEndpoint、TokenEndpoint、CheckTokenEndpoint、AuthorizationServerEndpointsConfiguration
授权服务的配置如下:
/**
* 授权服务器相关的配置
*/
@Configuration
@EnableAuthorizationServer
public class GrantServerConfig extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(ClientDetailsServiceConfigurer clients)
throws Exception {
clients.inMemory()
.withClient("cloud_grant")
.secret("cloud_grant")
.redirectUris("http://127.0.0.1:8001/login")
// 授权码模式
.authorizedGrantTypes("authorization_code")
.scopes("res_list", "res_info");
}
}
资源服务的配置如下:
/**
* 配置资源服务器的相关的配置,进行授权
*/
@Configuration
@EnableResourceServer
//@Order(Integer.MAX_VALUE)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.requestMatchers()
.antMatchers("/api/**");
}
}
受保存的资源服务列表代码如下:
@RestController
@RequestMapping("/api/res")
public class ResourceController {
@GetMapping
public Res getRes(){
Res res=new Res();
res.setId(1);
res.setResCode("home_list");
res.setResName("主页列表");
return res;
}
}
输入如下的请求地址
http://127.0.0.1:8080/oauth/authorize?client_id=cloud_grant&redirect_uri=http://127.0.0.1:8001/login&response_type=code&scope=res_info
出现如下问题:
User must be authenticated with Spring Security before authorization can be completed.
解决办法
加入如下的配置
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.requestMatchers()
.antMatchers("/oauth/**","/login/**","/logout/**")
.and()
.authorizeRequests()
.antMatchers("/oauth/**").authenticated()
.and()
.formLogin().permitAll(); //新增login form支持用户登录及授权
}
}
再输入如下的请求地址
http://127.0.0.1:8080/oauth/authorize?client_id=cloud_grant&redirect_uri=http://127.0.0.1:8001/login&response_type=code&scope=res_info
输入安全用户名和密码:
这是因为密码加密配置器没有找到的原因,增加一个密码配置器就可以了
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
2019-12-28 20:33:45.298 INFO 5904 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 7 ms
2019-12-28 20:33:45.429 WARN 5904 --- [nio-8080-exec-1] o.s.s.c.bcrypt.BCryptPasswordEncoder : Encoded password does not look like BCrypt
2019-12-28 20:34:11.250 WARN 5904 --- [nio-8080-exec-4] o.s.s.c.bcrypt.BCryptPasswordEncoder : Encoded password does not look like BCrypt
2019-12-28 20:34:21.744 WARN 5904 --- [nio-8080-exec-7] o.s.s.c.bcrypt.BCryptPasswordEncoder : Encoded password does not look like BCrypt
2019-12-28 20:34:40.954 WARN 5904 --- [io-8080-exec-10] o.s.s.c.bcrypt.BCryptPasswordEncoder : Encoded password does not look like BCrypt
定位到相关的源代码可知,密码的规则的长度和复杂度不够
解析办法如下
public static void main(String[] args) {
String result=new BCryptPasswordEncoder().encode("yang123456");
System.out.println("result = [" + result + "]");//$2a$10$6kzPmiwy3mp4J8gbY7ooleQiCik5llTxhjQXpNJkilsGMJOs7o0hC
}
修改application.yml的密码替换成上面程序得到的经过BCryptPasswordEncoder编码之后密码,也就是
spring:
security:
user:
name: yangyang
password: $2a$10$6kzPmiwy3mp4J8gbY7ooleQiCik5llTxhjQXpNJkilsGMJOs7o0hC
执行成功,后面再补充其他的授权模式