oauth2

来源:互联网 发布:安卓手机编程软件 编辑:程序博客网 时间:2024/06/03 22:00

OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版。
授权使用的场景是什么呢?其实现在市面上有好多的列子,最常用的就是第三方登录。其实他们就是用oauth2来控制资源权限的授权。就比如csdn可以使用qq登录,然后获取qq上自己的信息来进行csdn的注册,省了用户访问网站动不动就要注册的麻烦。oauth2最要是通过token来验证用户的权限。基本上是围绕着token。oauth2要与security一起,一个用于认证一个用于授权。
而oauth2的主要是分了几个模式:
1、密码模式。
2、客户端模式
3、简化模式
4、授权码模式
具体的可以参考这个链接地址这里写链接内容
在进入具体模式的情况下要先弄清楚spring security 和oauth2里面的拦截器,这个我也不多讲了,自己可以百度一下(因为好多)。
废话不多说就直接上代码吧。ps(我这里是基于spring boot 和spring cloud来设计的)
一、密码模式
密码模式:其实就是将用户的用户名和密码给第三方用户,他拿到你的用户名和密码去获取相应的token。最后带着token去访问相应的接口来获取你的自己的数据。
网上好多的例子都是基于内存来实现的,就是将用户名和密码放在内存中,但是现实情况中是将token以及用户信息和第三方信息都是放在数据库进行存储的。所以我们接下来的几种模式都会基于数据库来设计。
首先我们要建立相应的数据库表,其实oauth2已经帮我们设计好了一张数据库表,你只要自己导入进行就可以了。具体怎么设计以及每张表的作用可以参考这各链接:这里写链接内容
数据库弄好了我们就可以开始弄代码了,密码模式首先你得能验证用户账号和密码是否正确吧,而这个密码和用户账号是在认证服务进行认证的,就比如在qq上的用户不可能将认证给第三方吧,oauth2的好处就是,我们以qq做例子,认证和资源都是在qq服务器进行的,而第三方客户端需要带着自己的client_id以及用户的账号和密码来获取相应的token。拿到token就相当于用户同意第三方拿取该用户的信息。不多说直接代码吧。
首先要了解几个接口:UserDetailsService(看这个名字就知道获取用户的细节)以及UserDetails这两个类,他们做的主要作用就是判断用户账号是否正确,继承UserDetailsService要实现loadUserByUsername进行判断用户账号密码是否正确,还有一个就是clientDetailsService这个主要是用于认证第三方客户端的,他要实现loadClientByClientId,其实原理和上面的一样。如下代码:

@Service("UserDetailsService")public class AuthUserDetailsServiceImpl implements UserDetailsService {  @Autowired  private AuthUserDetailsDao authUserDetailsDao;  /**   * 获取用户信息 TODO: 加缓存   */  @Override  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {    User user = authUserDetailsDao.findUser(username);//查询数据库是否有改用户    if (user == null) return null;    List<Role> roles = authUserDetailsDao.findRolesByUserid(user.getId());//获取用户的相应的角色    UserRepositoryUserDetails userDetails = new UserRepositoryUserDetails(user, roles);//进行用户账号和密码的匹对    return userDetails;  }}

而clientDetailsService的代码如下:

@Override  public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {    /**clients            .inMemory()                .withClient("clientapp")                    .authorizedGrantTypes("password", "refresh_token")//有什么方式获取token                    .authorities("USER")                    .scopes("read", "write")//希望获得的权限                    .resourceIds(RESOURCE_ID)                    .secret("123456");*/这是放在内存的第三方的信息    ClientDetail clientDetail = dao.getById(clientId);    //TODO:改数据库查询    ClientDetails client = new SampleClientDetails(clientDetail);//查找是否有第三方的信息    return client;  }

这时候我们使用数据库方式的已经弄好了,这里我是使用mybatis的,具体的数据库配置我就不贴出来了。记住第三方那边一定要有密码模式(authorizedGrantTypes这个字段添加,多个用,分割)的方式,不然无法使用该模式进行访问。还有就是要重写tokenstore这个类,其实oauth2里面有持久化的实现。好像是jdbctokenstore这个类,我们自己重写生成token以及涮洗的都是仿造这个类来弄的。

原创粉丝点击