第七章 Auth2微服务鉴权jwt方式笔记

一、搭建认证服务器

JWT:json web token是一种无状态的权限认证方式,一般用于前后端分离,时效性比较极端的权限校验,jwt模式获取token跟前面的客户端、密码、授权码模式是一样的,只是需要配置秘钥。

1、服务端环境准备

新建认证服务器:springcloud-micro-jwt

1.1、添加pom依赖,与前面的其他模式一样

<!-- 添加oath2框架依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>

1.2、添加配置

不需要添加

1.3、核心配置类代码实现

/**
 * JWT方式配置类
* */
@Configuration
@EnableAuthorizationServer
public class OAuth2JwtConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;
    @Autowired
    private MyUserDetailsService myUserDetailsService;
    @Autowired
    private DataSource dataSource;
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        // 配置token的存储方式为JwtTokenStore
        endpoints.tokenStore(tokenStore())
                // 配置用于JWT私钥加密的增强器
                .tokenEnhancer(jwtTokenEnhancer())
                // 配置安全认证管理
                .authenticationManager(authenticationManager)
                .userDetailsService(myUserDetailsService);
    }
    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(jwtTokenEnhancer());
    }
    @Bean
    protected JwtAccessTokenConverter jwtTokenEnhancer() {
        // 配置jks文件
        KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("springcloud-micro-jwt.jks"), "123456".toCharArray());
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setKeyPair(keyStoreKeyFactory.getKeyPair("springcloud-micro-jwt"));
        return converter;
    }
    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        // 对获取Token的请求不再拦截
        oauthServer.tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()");// 验证获取Token的验证信息
    }
}

1.4、WebSecurity配置代码如下所示:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserServiceDetail userServiceDetail;
    @Override
    public @Bean
    AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();//关闭CSRF
//                .exceptionHandling()
//                .authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
//                .and()
//                .authorizeRequests()
//                .antMatchers("/oauth/**").permitAll()
               .antMatchers("/**").authenticated()
//                .and()
//                .httpBasic();
        http.requestMatchers().anyRequest()
                .and()
                .authorizeRequests()
                .antMatchers("/oauth/**").permitAll();
    }
    @Bean
    PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }
    @Bean
    public static NoOpPasswordEncoder noOpPasswordEncoder() {
        return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userServiceDetail).passwordEncoder(passwordEncoder());
    }
}

1.5、HttpSecurity配置属性说明:

access(String) 如果给定的SpEL表达式计算结果为true,就允许访问

anonymous() 允许匿名用户访问

authenticated() 允许认证的用户进行访问

denyAll() 无条件拒绝所有访问

fullyAuthenticated() 如果用户是完整认证的话(不是通过Remember-me功能认证的),就允许访问

hasAuthority(String) 如果用户具备给定权限的话就允许访问

hasAnyAuthority(String…)如果用户具备给定权限中的某一个的话,就允许访问

hasRole(String) 如果用户具备给定角色(用户组)的话,就允许访问/

hasAnyRole(String…) 如果用户具有给定角色(用户组)中的一个的话,允许访问.

hasIpAddress(String 如果请求来自给定ip地址的话,就允许访问.

not() 对其他访问结果求反.

permitAll() 无条件允许访问

rememberMe() 如果用户是通过Remember-me功能认证的,就允许访问

1.6、启动服务测试

...

2、客户端环境准备

新建业务客户端项目:springcloud-micro-jwt-web

1.1、添加pom依赖

<!-- 添加oath2框架依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>

1.2、添加配置application.yml

#spring:
#  security:
#    user:
#      name: admin
#      password: admin
# 服务鉴权配置
security:
  oauth2:
    resource:
      jwt:
        key-uri: http://localhost:8081/jwt/oauth/token_key
      service: uni-meta-provider
    client:
      access-token-validity-seconds: 36000
      clientId: pc
      client-secret: 123456
      access-token-uri: http://localhost:8081/oauth/token
      grant-type: password # refresh_token client_credentials password authorization_code
      scope: all

1.3、添加配置类代码

@Configuration
public class JwtConfig {
    @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;
    @Bean
    @Qualifier("tokenStore")
    public TokenStore tokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter);
    }
    @Bean
    public JwtAccessTokenConverter jwtTokenEnhancer() {
        // 用作JWT转换器
        JwtAccessTokenConverter converter =  new JwtAccessTokenConverter();
        Resource resource = new ClassPathResource("public.cert");
        String publicKey;
        try {
            publicKey = new String(FileCopyUtils.copyToByteArray(resource.getInputStream()));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //设置公钥
        converter.setVerifierKey(publicKey);
        return converter;
    }
}

资源服务器开启@EnableResourceServer

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Autowired
    private TokenStore tokenStore;
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/user/login","/user/register").permitAll()
                .antMatchers("/**").authenticated();
    }
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenStore(tokenStore);
    }
}

1.4、启动服务测试

...

3、生成秘钥、公钥文件

3.1、生成秘钥文件

cd到jdk的bin目录执行该指令,会在bin目录下生成xxx.jks文件,把该文件放到认证服务工程里面的resources目录下:

管理员身份运行cmd执行命令:keytool -genkeypair -alias springcloud-micro-jwt -validity 3650 -keyalg RSA -dname "CN=jwt,OU=jtw,O=jwt,L=zurich,S=zurich, C=CH" -keypass 123456 -keystore springcloud-micro-jwt.jks -storepass 123456

生成如下文件:springcloud-micro-jwt.jks

 

然后将该文件放到认证服务器的resources目录下。

3.2、生成公钥

keytool -list -rfc --springcloud-micro-jwt.jks | openssl x509 -inform pem -pubkey

把生成的公钥内容放到public.cert文件中,内容如下:

 

把公钥文件放到客户端的resources目录下。

二、JWT token获取

1、密码模式获取jwt token

访问地址:

 

密码模式获取token:

Jwt的token信息分成三个部分,用“.”号分割的。

第一部分:头信息,通过base64加密生成。

第二部分:有效载荷,通过base64加密生成。

第三部分:签名,根据头信息中的加密算法通过,RSA(base64(头信息) + “.” + base64(有效载荷))生成的第三部分内容。

可以到jwt的官网看看这三部分信息的具体内容:jwt官网jwt.io

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值