Oauth2实现认证授权,单点登录案例

1.项目地址

2.基本概念

主要角色

  • 第三方应用程序Third-party application): 又称之为客户端(client
  • 服务提供商HTTP service): 我们的云笔记产品以及 QQ、微信等都可以称之为“服务提供商”。
  • 资源所有者Resource Owner): 又称之为用户(user)。
  • 用户代理User Agent): 比如浏览器,代替用户去访问这些资源。
  • 认证服务器Authorization server):
    即服务提供商专门用来处理认证的服务器,简单点说就是登录功能(验证用户的账号密码是否正确以及分配相应的权限)
  • 资源服务器Resource server):
    即服务提供商存放用户生成的资源的服务器。它与认证服务器,可以是同一台服务器,也可以是不同的服务器。简单点说就是资源的访问入口,比如“云笔记服务”和“云相册服务”都可以称之为资源服务器。

grant_type:端点类型

  • authorization_code : 授权码模式,根据client账号密码获取授权码code,在根据授权码获取token
  • password : 密码模式,使用用户账号密码登录获取token
  • refresh_token: 开放端点进行刷新access_token
  • client_credentials: 客户端模式
  • implicit: 简化模式
  • token_key: 用于单点登录的端点
  • token_error:错误回调端点

client_detail:客户端详情

  • client_id: 客户端唯一ID,相当于账号

  • client_secret: 客户端秘钥,相当于密码

  • resource_ids: 客户端拥有资源

  • scope: 客户端权限范围标识

  • authorized_grant_types: 同上grant_type

  • web_server_redirect_uri: 授权成功后的回调地址

  • authorities: 客户端拥有的权限资源

  • access_token_validity: token的过期时间

  • refresh_token_validity: refresh_token的失效时间

  • additional_information: 附加信息

  • autoapprove: 开启自动授权,true or false

  • 主要流程图

在这里插入图片描述

2.认证服务器搭建

  1. Pom.xml
    	 <!-- Spring Cloud 和 oauth2支持的同时需要引用web开始filter的支持 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>
              <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

2. 配置授权服务


@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private DataSource dataSource;

    @Autowired
    @Qualifier("jwtTokenStore") //需要指定名称,不然注册其他的。
    private TokenStore tokenStore;

    @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;

    /**
     * 刷新令牌需要使用自定义的授权服务
     */
    @Autowired
    @Qualifier("userDetailsServiceImpl")
    private UserDetailsService userDetailsService;



    /**
     * JDBC令牌存储
     * 访问形式: xxx/xxx?access_token=xxxx
     * @return
     */
//    @Bean
//    public TokenStore tokenStore() {
//        // 基于 JDBC 实现,令牌保存到数据
//        return new JdbcTokenStore(dataSource);
//    }

    @Bean
    public ClientDetailsService jdbcClientDetails() {
        // 基于 JDBC 实现,需要事先在数据库配置客户端信息
        return new JdbcClientDetailsService(dataSource);
    }

    /**
     * 配置token的存储和时间等属性
     * @return
     */
//    @Bean
//    public DefaultTokenServices tokenServices(){
//        DefaultTokenServices tokenServices = new DefaultTokenServices();
//        tokenServices.setAccessTokenValiditySeconds(20);//设置20秒过期
//        tokenServices.setRefreshTokenValiditySeconds(666);//设置刷新token的过期时间
//        tokenServices.setTokenStore(tokenStore);
//        return tokenServices;
//    }



    /**
     * http://localhost:8080/oauth/token
     * 参数:
     * grant_type : authorization_code,password
     * code:  授权密码
     * 或者:
     * username:xx
     * password:xx
     *
     * 并且要加上Authorization的用户名密码就是
     * client_id 和  client_secret
     * @param endpoints 授权服务器端点令牌配置
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        // 设置令牌
        endpoints
                .authenticationManager(authenticationManager)
                //刷新token需要配置userDetailsService重新加载权限,需要在authenticationManager之后配置
                .userDetailsService(userDetailsService)
                 .tokenStore(tokenStore)
                .accessTokenConverter(jwtAccessTokenConverter);
               // .tokenServices(tokenServices());

    }


    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    security

        // exposes public key for token verification if using JWT tokens
        // 允许Jwt token验证秘钥
        .tokenKeyAccess("permitAll()")
        // used by Resource Servers to decode access tokens
        // 允许已认证的资源服务器解码token,单点登录需要
        .checkTokenAccess("isAuthenticated()")

        /**
         * allowFormAuthenticationForClients是为了注册clientCredentialsTokenEndpointFilter
         * clientCredentialsTokenEndpointFilter,解析request中的client_id和client_secret
         * 构造成UsernamePasswordAuthenticationToken,然后通过UserDetailsService查询作简单的认证而已
         * 一般是针对password模式和client_credentials
         * 当然也可以使用http basic认证
         * 如果使用了http basic认证,就不用使用clientCredentialsTokenEndpointFilter,因为本质是一样的
         */
        .allowFormAuthenticationForClients();
    }

    /**
     * 客户端配置
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        // 读取客户端配置
        clients.withClientDetails(jdbcClientDetails());
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值