之前的文章介绍SpringSocal,本章学习一下SpringSecurityOauth 的基本原理。
应用场景
传统的Web应用,是浏览器直接访问Application-Server,是基于Session-Cookie的策略,把用户信息存储到Session中,但是现在的Web应用,大多是前后端分离,并且还有APP类的应用。无论是App还是Web-Server,对Application-Server而言,都相当于第三方应用。这时的Session-Cookie策略会有很多弊端
- 开发繁琐
- 安全性和客户体验差
- 有些前端技术不支持Cookie,如小程序
而基于令牌的形式可以可好的解决以上问题,用户信息存储在令牌中,每次访问请求都要带着Token,Application-Server通过Token来验证用户的权限。
比较
- SpringSocial主要是做客户端的工作,可以快速实现客户端角色,客服端去向服务提供商获取信息,要去配置授权模式上的各个步骤,比如获取授权码路径,获取accesstoken,获取用户信息等。
- Spring Security OAuth,可以快速实现服务提供商角色,内部已经实现好了OAuth2的四种授权模式,可以把自定义的认证,使其支持Token、资源服务器的配置。
Spring Security Oauth 简介
SpringSecurityOAuth其实已经帮我们默认实现了以下一些东西:
- 认证服务器
- 四种授权模式的默认实现
- Token的生成存储
- 资源服务器
- OAuth2AuthenticationProcessingFilter(拦截用户请求中的token并从认证服务器中寻找对应的用户信息)
一个简单的实现
1. 认证服务器的实现
1.1 @EnableAuthorizationServer
@Configuration
@EnableAuthorizationServer
public class ImoocAuthorizationServerConfig {
}
通过@EnableAuthorizationServer注解,认证服务器就默认实现了
1.2 给测试用户配置ROLE_USER角色
@Component
public class DemoUserDetailsService implements UserDetailsService, SocialUserDetailsService {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
logger.info("表单登录用户名:" + username);
return buildUser(username);
}
@Override
public SocialUserDetails loadUserByUserId(String userId) throws UsernameNotFoundException {
logger.info("设计登录用户Id:" + userId);
return buildUser(userId);
}
private SocialUserDetails buildUser(String userId) {
// 根据用户名查找用户信息
//根据查找到的用户信息判断用户是否被冻结
String password = passwordEncoder.encode("123456");
logger.info("数据库密码是:"+password);
return new SocialUser(userId, password,
true, true, true, true,
AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_USER"));
}
}
SpringSecurityOauth默认用户要至少拥有USER角色才可以,不然会报403错误
1.3 配置 clientId 和 clientSecret
security.oauth2.client.clientId = imooc
security.oauth2.client.clientSecret = imoocsecret
在启动日志中,我们可以看到认证服务器的相关接口和我们配置的clientId 和 clientSecret,如果没有配置,则SpringSecurityOauth会帮我们生成默认的clientId 和 clientSecret
- /oauth/authorize 方法是用来获取授权码
- /oauth/token 方法是用来获取令牌
security.oauth2.client.clientId = imooc
security.oauth2.client.secret = ****
1.3 获取授权码
参考官网:获取授权码 接口所需的相关参数,请求如下
http://localhost:8080/oauth/authorize?response_type=code&client_id=imooc&redirect_uri=http://csdn.net&scope=all
1.3.1 会先提示你输入用户名和密码,
- username: admin
- password: 123456
1.3.2 然后进行授权,请求时会把用户信息进行编码,放到请求头中。
Authorization: Basic YWRtaW46MTIzNDU2
1.3.3 最后授权码会在回调地址上带上
https://www.csdn.net/?code=vgxmH1
1.4 获取令牌
首先需要在请求头中带上客户端用户名和密码
请求参数如下
得到请求结果如下
{
"access_token": "69be77ad-1409-4c92-8261-4e63221c4398",
"token_type": "bearer",
"refresh_token": "448fd84d-a6d3-4c68-858a-d904cd813cf3",
"expires_in": 43199,
"scope": "all"
}
2.资源服务器的实现
2.1 @EnableResourceServer
资源服务器的实现只需要加个注解就行了
@Configuration
@EnableResourceServer
public class ImoocResourceServerConfig {
}
2.2 然后就可以带着token去访问资源了