成都网站建设设计

将想法与焦点和您一起共享

SpringCloud中怎么使用OAuth2.0实现鉴权

本篇文章给大家分享的是有关SpringCloud中怎么使用OAuth2.0实现鉴权,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

10年积累的成都网站制作、成都网站建设、外贸营销网站建设经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先建设网站后付款的网站建设流程,更有龙马潭免费网站建设让你可以放心的选择与我们合作。

SpringSecurity

Spring Security是一个功能强大、高度可定制的身份验证和访问控制框架。它用于保护基于Spring的应用程序。Spring Security是一个专注于向Java应用程序提供身份验证和授权的框架。 与所有Spring项目一样,Spring安全的真正威力在于它可以很容易地扩展以满足定制需求。

OAuth3.0

OAuth 2.0是用于授权的行业标准协议。OAuth3.0注重客户端开发人员的简单性,同时为Web应用程序、桌面应用程序、移动电话和客厅设备提供特定的授权流。 更多请参考 OAuth3.0

OAuth3.0模式

模式应用场景描述
授权码(Auth Code)成功后跳转其他页面,如第三方微信登录等
简化模式(implicit)不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌
密码模式(password credentials)web页面用户名密码登录
客户端模式(client credentials)主要针对openapi,使用apikey和secretkey方式
JWT

JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案。更多请参考 JWT入门教程

2、前期必备

核心pom依赖如下:



    org.springframework.boot
    spring-boot-starter-security



    org.springframework.security.oauth
    spring-security-oauth3
    2.3.6.RELEASE



    org.springframework.boot
    spring-boot-starter-web



    org.springframework.boot
    spring-boot-starter-data-redis



    org.springframework.boot
    spring-boot-starter-security



    org.slf4j
    slf4j-api
    1.7.25


    org.projectlombok
    lombok

创建一个rest接口用于后面测试资源

@Slf4j
@RestController
public class TestSecurityController {
    @GetMapping("/product/{id}")
    public String getProduct(@PathVariable String id) {
        //for debug
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return "product id : " + id;
    }

    @GetMapping("/order/{id}")
    public String getOrder(@PathVariable String id) {
        //for debug
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return "order id : " + id;
    }
}

3、操作步骤

很多文章写的特别复杂,其实主要的内容也就分为下面几步

3.1、授权服务器AuthorizationServerConfigurerAdapter

需要自定义授权服务器,继承AuthorizationServerConfigurerAdapter,详细代码如下

@Configuration
@EnableAuthorizationServer
public   class AuthServerConfiguration extends AuthorizationServerConfigurerAdapter {
    private static final String DEMO_RESOURCE_ID = "order";

    @Autowired
    AuthenticationManager authenticationManager;
    @Autowired
    RedisConnectionFactory redisConnectionFactory;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //配置两个客户端,一个用于password认证一个用于client认证
        String secret = new BCryptPasswordEncoder().encode("123456");////对密码进行加密
        clients.inMemory().withClient("client_1")
                .resourceIds(DEMO_RESOURCE_ID)
                .authorizedGrantTypes("client_credentials", "refresh_token")
                .scopes("select")
                .authorities("client")
                .secret(secret)
                .and().withClient("client_2")
                .resourceIds(DEMO_RESOURCE_ID)
                .authorizedGrantTypes("password", "refresh_token")
                .scopes("select")
                .authorities("client")
                .secret(secret);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                .tokenStore(new RedisTokenStore(redisConnectionFactory))
                .authenticationManager(authenticationManager);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        //允许表单认证
        oauthServer.allowFormAuthenticationForClients();
    }

}

3.2、资源服务器ResourceServerConfigurerAdapter

同上,需要实现自己的资源服务器,继承ResourceServerConfigurerAdapter,详细代码如下

@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
    private static final String DEMO_RESOURCE_ID = "order";
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.resourceId(DEMO_RESOURCE_ID).stateless(true);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
                // Since we want the protected resources to be accessible in the UI as well we need
                // session creation to be allowed (it's disabled by default in 2.0.6)
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .and()
                .requestMatchers().anyRequest()
                .and()
                .anonymous()
                .and()
                .authorizeRequests()
//                    .antMatchers("/product/**").access("#oauth3.hasScope('select') and hasRole('ROLE_USER')")
                .antMatchers("/order/**").authenticated();//配置order访问控制,必须认证过后才可以访问
        // @formatter:on
    }
}

3.3、配置SpringSecurity

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    protected UserDetailsService userDetailsService(){
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        String pwd = new BCryptPasswordEncoder().encode("123456");//对密码进行加密
        manager.createUser(User.withUsername("user_1").password(pwd).authorities("USER").build());
        manager.createUser(User.withUsername("user_2").password(pwd).authorities("USER").build());
        return manager;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .requestMatchers().anyRequest()
                .and()
                .authorizeRequests()
                .antMatchers("/oauth/*").permitAll();
    }
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        AuthenticationManager manager = super.authenticationManagerBean();
        return manager;
    }

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

4、测试

我们设计的是product服务可以匿名访问,而order服务需要签名才可以访问,验证如下:

  • password模式 利用postman进行post访问http://localhost:8080/oauth/token?username=user_1&password=123456&grant_type=password&scope=select&client_id=client_2&client_secret=123456 获取如下结果

{
    "access_token": "c2340190-48f3-4291-bb17-1e4d51bcb284",
    "token_type": "bearer",
    "refresh_token": "03ee113c-a942-452a-9918-7ffe24472a7f",
    "expires_in": 40399,
    "scope": "select"
}

SpringCloud中怎么使用OAuth2.0实现鉴权

  • client模式 同样利用postman的POST方式访问http://localhost:8080/oauth/token?grant_type=client_credentials&scope=select&client_id=client_1&client_secret=123456 结果如下

{
    "access_token": "05a4e614-f34b-4c83-9ec1-89ea55c0afd2",
    "token_type": "bearer",
    "expires_in": 40396,
    "scope": "select"
}

SpringCloud中怎么使用OAuth2.0实现鉴权

对资源进行访问
  • product服务:访问http://localhost:8080/product/1得到如下数据
    product id : 1

  • order服务:访问http://localhost:8080/order/1,返回数据如下



Full authentication is required to access this resource

unauthorized

验证结果,说明order服务需要签名才可以访问,接下来,我们输入签名访问order服务。 我们分别利用上面password模式获取的token,访问 http://localhost:8080/order/1?access_token=c2340190-48f3-4291-bb17-1e4d51bcb284 得到数据 order id : 1

通用利用client模式获取的token,访问 http://localhost:8080/order/1?access_token=05a4e614-f34b-4c83-9ec1-89ea55c0afd2 同样可以得到 order id : 1

以上就是SpringCloud中怎么使用OAuth2.0实现鉴权,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注创新互联行业资讯频道。


网页标题:SpringCloud中怎么使用OAuth2.0实现鉴权
网页链接:http://chengdu.cdxwcx.cn/article/jopgec.html