1.体验四种模式
1.1项目搭建
1.1.1导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
1.1.2编写配置类
1.SpringSecurity的配置类
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("gaoxi")
.password(passwordEncoder().encode("123456")).roles("admin");
}
}
2.AuthorizationServerConfig认证服务器配置类
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("yurun")
.secret(passwordEncoder.encode("yurun"))
.resourceIds("demo")
.scopes("all")
.authorizedGrantTypes("password","refresh_token","implicit","client_credentials","authorization_code")
.redirectUris("http://www.baidu.com");
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.allowFormAuthenticationForClients()
.checkTokenAccess("isAuthenticated()");
}
}
1.2授权码模式
1.浏览器输入 http://localhost:8080/oauth/authorize?response_type=code&client_id=yurun&redirct_uri=http://www.baidu.com&scope=all
自动跳转到登录页面
2.输入用户名和密码(程序中设置的),并点击登录
3.浏览器提示是否授权,点击授权后,自动跳转到回调地址并携带授权码
4.使用postman获取accesstoken
5.点击发送后,得到access_token
1.3密码模式
1.使用post发送获取access_token的请求(http://localhost:8080/oauth/token?grant_type=password&username=gaoxi&password=123456&client_id=yurun&client_secret=yurun
)
2.查看获取到的信息
1.4简化模式(implicit)
1.浏览器请求地址(http://localhost:8080/oauth/authorize?response_type=token&client_id=
yurun
)
2.自动跳转到回调地址并携带token
1.5客户端模式
使用postman请求地址(http://localhost:8080/oauth/token?grant_type=client_credentials&client_id=yurun&client_secret=yurun
)
2.一个简单DEMO
功能描述:搭建2个服务,1个提供Oauth2的认证服务,颁发access_token。另一个作为资源服务。
2.1认证服务器的搭建
1.导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.编写SpringSecurity配置类
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("gaoxi")
.password(passwordEncoder().encode("123456"))
.roles("admin");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
}
}
3.编写认证服务配置类
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.allowFormAuthenticationForClients()
.checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore())
.authenticationManager(authenticationManager)
.accessTokenConverter(jwtAccessTokenConverter());
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("yurun")
.secret(passwordEncoder.encode("yurun"))
.authorizedGrantTypes("refresh_token","password")
.scopes("all")
.resourceIds("resource1") ;
}
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter(){
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("my-sign-key"); //资源服务器需要配置此选项方能解密jwt的token
return converter;
}
@Bean
public TokenStore tokenStore(){
return new JwtTokenStore(jwtAccessTokenConverter());
}
}
2.2资源服务器的搭建
1.pom文件(同上)
2.资源服务器配置类
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(securedEnabled = true,jsr250Enabled = true,prePostEnabled = true)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter(){
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("my-sign-key");
return converter;
}
@Bean
public TokenStore tokenStore(){
return new JwtTokenStore(jwtAccessTokenConverter());
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated();
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId("resource1").stateless(true);
resources.tokenStore(tokenStore());
}
}
3.Controller层的编写
@RestController
public class MyController {
//用户没有user角色,登录后也不可访问
@Secured(value = "ROLE_user")
@RequestMapping("queryList")
public String queryList(){
return "stu List";
}
//用户有admin角色,这个接口在登录后可以访问
@Secured(value = "ROLE_admin")
@RequestMapping("queryById")
public String queryById(){
return "user";
}
}
2.3运行流程
1.认证服务器在 8080端口、资源服务器在8081端口
2.尝试访问资源服务器上的2个接口
2.postman使用密码模式请求认证服务器(端口8080),获取access_token
3.拷贝access_token,放入请求资源服务的接口参数中
①对于queryById,需要角色admin,用户名为gaoxi的这个用户有admin角色所以可以访问成功
②对于queryList,需要user角色,此用户没有角色所以仍然访问失败
③用户名:gaoxi这个用户是放在内存中的,角色也是在代码中设定的。
3.错误默认返回整理
1.没有加入Authorization头
DENY 4012.错误的token
DENY 401
3.过期的token
Deny 401