三 配置授权服务器

创建认证服务auth

(1)引入依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-oauth2</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-jwt</artifactId>
    <version>1.1.1.RELEASE</version>
</dependency>

第一步、创建配置类

自定义配置类OAuth2AuthorizationServer,继承AuthorizationServerConfigurerAdapter,添加注解
@Configuration
@EnableAuthorizationServer

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter {

}

重写AuthorizationServerConfigurerAdapter中的三个方法,配置授权服务器

public class AuthorizationServerConfigurerAdapter implements AuthorizationServerConfigurer {

    public AuthorizationServerConfigurerAdapter() {
    }

    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    }

    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    }

    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    }
}

这三个方法的作用:

ClientDetailsServiceConfigurer:
配置客户端信息,客户端信息在这里进行初始化,可以在这里写死也可以通过数据库来存储和调取

AuthorizationServerEndpointsConfigurer:
配置令牌服务和令牌的访问端点

AuthorizationServerSecurityConfigurer:
配置令牌端点的安全约束

第二步、配置客户端信息

配置客户端信息的 主要配置项:
clientId:客户端id
secret: 客户端秘钥
scope:允许的授权范围
authorizedGrantTypes:允许客户端使用的授权类型
authorities:客户端可以使用的权限

客户端信息 能够在应用程序运行的时候进行更新 可以使用内存存储也可以存储在关系型数据库中

接下来演示用内存的方式存储客户端信息,配置如下:

    /**
     * 配置基于内存或JDBC的客户端信息
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()// 使用内存存储
                .withClient("c1")//客户端id
                .secret(new BCryptPasswordEncoder().encode("secret"))//客户端秘钥
                .resourceIds("res1")//资源列表
                /**
                 * 允许给客户端授权的5种授权类型:
                 *  1 "authorization_code"  授权码模式, 2 "password" 密码模式, 3 "client_credentials" 客户端模式
                 *  4 "implicit" 隐式模式, 5 "refresh_token" 刷新令牌
                 */
                .authorizedGrantTypes("authorization_code","password","client_credentials","implicit","refresh_token")

                .scopes("all")//允许的授权范围
                .autoApprove(false) //false: 如果是授权码模式 跳转到授权页面
                .redirectUris("http://www.baidu.com");//加上验证回调地址
    }

3、令牌服务底层实现原理

(1)底层源码分析:
AuthorizationServerTokenServices接口定义了一些操作使得你可以对令牌进行一些必要的管理;

DefaultTokenServices是AuthorizationServerTokenServices的实现类,可以使用它来设置令牌的格式和令牌的存储;

默认创建一个令牌时,使用随机值进行填充,除了持久化令牌是委托一个TokenStore接口来实现以外,其他功能都由DefaultTokenServices实现;

TokenStore这个接口有一个默认的实现类InMemoryTokenStore,如其命名,所有的令牌都被保存在了内存中。

(2)TokenStore的3个实现类简介:
InMemoryTokenStore:该实现类被默认采用,这种方式是将令牌保存到内存中,可以在开发阶段使用它做调试;

JdbcTokenStore:这是一个基于JDBC的实现类,令牌会被保存进关系型数据库。这种实现方式可以在不同的服务器之间共享令牌信息,使用该实现类要导入spring-jdbc依赖

JwtTokenStore:它可以把令牌相关的数据进行编码,不需要进行存储

4、令牌服务代码实现

    @Autowired
    ClientDetailsService clientDetailsService;

    @Autowired
    TokenStore tokenStore;

    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }

    @Bean
    public AuthorizationServerTokenServices tokenServices() {
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setClientDetailsService(clientDetailsService);
        tokenServices.setSupportRefreshToken(true);
        tokenServices.setTokenStore(tokenStore);
        tokenServices.setAccessTokenValiditySeconds(7200); //令牌默认有效期2小时
        tokenServices.setRefreshTokenValiditySeconds(259200); //刷新令牌默认有效期3天

        return tokenServices;
    }

5、令牌访问端点配置

(1)配置授权类型

authenticationManager:
用于密码授权模式

authorizationCodeServices:
用于授权码模式

implicitGrantService:
用于设置隐式授权模式

userDetailsService:
配置自定义的userDetailsService实现类

tokenGranter:
四种授权模式不满足需求的情况下,做扩展增强
https://www.toobug.cn/post/2865.html

(2)配置授权端点的URL:

我们可以通过AuthorizationServerEndpointsConfigurer 对象的 pathMapping() 方法来配置端点URL链接,它有两个参数:
第一个参数:String 类型,它是这个端点URL的默认链接
第二个参数:String 类型,它是你要替换的URL链接

框架的默认URL链接如下:
/oauth/authorize:授权端点
/oauth/token:令牌端点
/oauth/confirm_access:用户确认授权提交端点
/oauth/error:授权服务错误信息端点
/oauth/check_token:用于资源服务访问的令牌解析端点
/oauth/token_key:如果使用的是JWT令牌,则为 提供公有密匙的端点

需要注意的是授权端点这个URL应该被spring security保护起来,只供授权用户访问

6、配置令牌端点的安全约束

AuthorizationServerSecurityConfigurer用来配置令牌端点的安全约束,配置如下:

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security
                 //tokenkey端点完全公开
                .tokenKeyAccess("permitAll()")

                 //checkToken端点完全公开
                .checkTokenAccess("permitAll()")
                 
                //允许表单认证
                .allowFormAuthenticationForClients();
    }

web安全配置

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 为特定的Http请求配置基于Web的安全约束
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //关闭csrf
        http.csrf().disable()
                //不通过Session获取SecurityContext
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                //对于登录接口,允许匿名访问
                .antMatchers("/user/login").anonymous() //匿名访问(未登录可访问,登录后不可访问)
                .antMatchers("/user/hello").hasAuthority("system:test:index")
                .anyRequest().authenticated();
        //允许跨域
        http.cors();
    }

    /**
     * 实例化AuthenticationManager对象,将它注入spring容器
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容