`
wx1569618008
  • 浏览: 75277 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

spring cloud 集成oauth2实现用户认证

 
阅读更多

spring-security-oauth2实现用户认证,客户端信息和用户信息存到数据库中,token使用比较频繁存到redis中

一、新建maven项目,

所需的依赖

 <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.3.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
        </dependency>
        <!-- 将token存储在redis中 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

二、配置资源服务器和授权服务器

客户端信息和用户信息存到数据库中,token使用比较频繁存到redis中,

package com.example.demo.config;

import com.example.demo.service.impl.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

import javax.sql.DataSource;
import java.util.Arrays;

/**
 * @author tudou
 * @Date 2018/11/14
 **/
@Configuration
public class OAuth2ServerConfig {

    private static final String DEMO_RESOURCE_ID = "order";

    @Configuration
    @EnableResourceServer
    protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

        @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("#oauth2.hasScope('select') and hasRole('ROLE_USER')")
                    .antMatchers("/hi/**").authenticated();//配置order访问控制,必须认证过后才可以访问
            // @formatter:on
        }
    }


    @Configuration
    @EnableAuthorizationServer
    protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {


        @Autowired
        AuthenticationManager authenticationManager;
        @Autowired
        RedisConnectionFactory redisConnectionFactory;

        String finalSecret = new BCryptPasswordEncoder().encode("123456");
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            //配置两个客户端,一个用于password认证一个用于client认证
//            clients.inMemory()
//                    .withClient("client")
//                    .resourceIds(DEMO_RESOURCE_ID)
//                    .authorizedGrantTypes("password", "refresh_token")
//                    .scopes("all", "read", "write")
//                    .accessTokenValiditySeconds(7200)
//                    .refreshTokenValiditySeconds(10000)
//                    .authorities("password")
//                    .secret(finalSecret);
            //这个地方指的是从jdbc查出数据来存储
            clients.withClientDetails(clientDetails());

        }

        @Autowired
        DataSource dataSource ;
        @Autowired
        UserDetailsServiceImpl userDetailsService;

        @Bean
        public ClientDetailsService clientDetails() {
            return new JdbcClientDetailsService(dataSource);
        }


        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

            endpoints.authenticationManager(authenticationManager)

                    //refresh_token 需要 UserDetailsService is required
                    .userDetailsService(userDetailsService)
                    .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
                    .tokenStore( tokenStore());
        }

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

        }

        @Bean
        public TokenStore tokenStore() {
//            return new InMemoryTokenStore();
            // 需要使用 redis 的话,放开这里
            return new RedisTokenStore(redisConnectionFactory);
        }



    }

}

三、配置spring security

认证用户时从数据库中取用户

package com.example.demo.config;

import com.example.demo.service.impl.UserDetailsServiceImpl;
import com.netflix.discovery.converters.Auto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.sql.DataSource;
import java.beans.Encoder;

/**
 * @author tudou
 * @Date 2018/11/14
 **/
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    DataSource dataSource ;

    @Autowired
    UserDetailsServiceImpl userDetailsService ;


    @Bean
    @Override
    protected UserDetailsService userDetailsService(){
//        JdbcUserDetailsManager manager = new JdbcUserDetailsManager();
//        manager.setDataSource(dataSource);

        return userDetailsService;

//        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
//        manager.createUser(User.withUsername("user_1").password(finalPassword).authorities("USER").build());
//        manager.createUser(User.withUsername("user_2").password(finalPassword).authorities("USER").build());
//        return manager;
    }


    @Bean
    PasswordEncoder passwordEncoder(){
//        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
        return new BCryptPasswordEncoder();
    }

    public static void main(String[] args) {
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
//        password 方案一:明文存储,用于测试,不能用于生产
//        String finalPassword = "123456";
//        password 方案二:用 BCrypt 对密码编码
        String finalPassword = bCryptPasswordEncoder.encode("123456");
        // password 方案三:支持多种编码,通过密码的前缀区分编码方式
//        String finalPassword1 = "{bcrypt}"+bCryptPasswordEncoder.encode("123456");
        System.out.println(finalPassword);
    }

//    String finalPassword = new BCryptPasswordEncoder().encode("123456");

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http.csrf().disable();

        http
                .requestMatchers().antMatchers("/oauth/**","/login/**","/logout/**")
                .and()
                .authorizeRequests()
                .antMatchers("/oauth/**").authenticated()
                .and()
                .formLogin().permitAll(); //新增login form支持用户登录及授权

        // @formatter:on
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        AuthenticationManager manager = super.authenticationManagerBean();
        return manager;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider
                = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService);
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    }


}

重写UserDetailsService

package com.example.demo.service.impl;

import com.example.demo.entity.Users;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;


/**
 * 重写用户服务
 *
 * @author:  ytzhou
 * @date:    2018/9/19 14:17
 * @version:  v1.0
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserServiceImpl userService;

    @Override
    public UserDetails loadUserByUsername(String userName) {
        Users user = userService.findOneByusername(userName);
        if (null == user) {
            throw new UsernameNotFoundException(userName);
        }
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
//        for (SysRole role : sysUser.getRoleList()) {
//            for (SysPermission permission : role.getPermissionList()) {
//                authorities.add(new SimpleGrantedAuthority(permission.getCode()));
//            }
//        }

        return new User(user.getUsername(),user.getPassword(), authorities);
    }
}

四、配置资源服务器

package com.example.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;

/*
* 提供 user 信息,所以 oauth2-server 也是一个Resource Server
* */
@Configuration
@EnableResourceServer
//@Order(3)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

 
}

 项目结构

75589fa26b4c365fdd6328f8c68ff6f5289.jpg

 

参考文章:http://blog.didispace.com/tags/Oauth2/

                  https://www.cnblogs.com/Irving/p/9306008.html

                  http://wiselyman.iteye.com/blog/2379419

转载于:https://my.oschina.net/u/3346425/blog/2961552

分享到:
评论

相关推荐

    Spring Cloud 集成OAuth2实现身份认证和单点登录

    本篇将深入探讨如何利用Spring Cloud集成OAuth2来实现身份认证和单点登录(Single Sign-On,简称SSO)。 OAuth2是一种授权框架,它允许第三方应用获取资源所有者的特定资源,同时保护了资源所有者的隐私信息。在...

    Spring Cloud 集成OAuth2实现身份认证和单点登录源代码

    在这个场景下,我们将探讨如何使用Spring Cloud集成OAuth2来实现身份认证和单点登录(SSO,Single Sign-On)。 OAuth2是一个开放标准,主要用于授权,它允许用户授权第三方应用访问其私有资源,而无需共享用户名和...

    springcloud整合oauth2和jwt

    通过以上步骤,我们可以在Spring Cloud项目中成功地整合OAuth2和JWT,实现权限认证,并利用MyBatis处理数据操作。这种集成方案为微服务架构提供了强大的安全基础,同时也保持了良好的性能和可扩展性。在实际开发中,...

    Spring Cloud 集成OAuth2实现的身份认证和单点登录(代码).zip

    本示例将详细介绍如何在 Spring Cloud 中集成 OAuth2 来实现身份认证和单点登录(Single Sign-On, SSO)。SSO 允许用户在一次登录后访问多个相互关联的应用系统,而无需再次进行身份验证,极大地提升了用户体验。 1...

    spring cloud oauth2 zuul 单点登录 认证授权

    在"spring-cloud-examples-master"这个压缩包中,可能包含了示例代码和配置文件,用于演示如何在Spring Cloud环境中集成OAuth2和Zuul实现单点登录。你可以通过阅读源码,理解它们的配置和交互方式,进一步了解如何在...

    Spring Cloud Alibaba 集成 Spring Security OAuth2.0 实现认证和授权

    分布式系统的认证和授权 分布式架构采用 Spring Cloud Alibaba 认证和授权采用 Spring Security OAuth2.0 实现方法级权限控制 网关采用 gateway 中间件 服务注册和发现采用 nacos

    springCloud+Oauth2

    `SpringCloud` 和 `OAuth2` 的结合提供了一种高效且灵活的方式来实现微服务架构中的服务发现、负载均衡和安全控制。本文将深入探讨如何利用这两个强大的框架来构建一个实现单点登录(Single Sign-On,SSO)及安全...

    springcloud微服务里的oauth2集成总结.docx

    ### Spring Cloud 微服务 OAuth2 集成详解 #### 版本声明的重要性 在集成Spring Boot、Spring Cloud以及Spring Security、Spring OAuth2时,必须明确指定这些框架的具体版本号。这是因为不同版本间的API和配置可能...

    SpringCloud(八):API网关整合OAuth2认证授权服务

    SpringCloud(八):API网关整合OAuth2认证授权服务。

    基于 Spring Cloud 2021 、Spring Boot 2.7、 OAuth2 的 RBAC 权限管理系统源码

    这是一个基于最新技术栈,包括Spring Cloud 2021、Spring Boot 2.7和OAuth2的RBAC(Role-Based Access Control)权限管理系统的源码项目。该项目旨在提供一套高效、安全的后端服务框架,用于实现用户权限的精细化...

    springcloud_oauth2.0-master.zip

    3. **用户认证**:实现用户认证逻辑,这可以是基于数据库的用户凭证验证,或者与其他身份验证服务(如LDAP)集成。 4. **令牌存储**:利用Redis存储OAuth2.0的令牌,提升性能并实现分布式环境下的令牌共享。 5. **...

    spring cloud oauth2

    Spring Cloud OAuth2 是一个基于 Spring Boot 和 Spring Security 的 OAuth2 实现,用于为微服务架构提供安全认证和授权服务。OAuth2 是一个开放标准,它允许用户授权第三方应用访问其私有资源,而无需分享用户名和...

    Spring Cloud 安全:集成OAuth2的数据库方式实现

    总的来说,Spring Cloud安全集成OAuth2的数据库方式实现涉及到多个步骤,包括配置客户端详情、创建授权服务器、配置资源服务器、处理用户认证以及创建客户端应用。这个过程需要对Spring Security OAuth2有深入理解,...

    springcloud-oauth2-security.rar

    《SpringCloud OAuth2 Security:构建安全微服务架构》 OAuth2是目前广泛应用于授权和访问控制的开放标准,尤其在微服务架构中扮演着至关重要的角色。Spring Cloud Security结合了OAuth2,为开发者提供了一套便捷的...

    基于Spring Cloud、OAuth2.0、Vue的前后端分离的系统

    系统可能集成了CAS、OAuth2.0或JWT等技术来实现多系统间的SSO,提升用户体验。 10. **Vue.js**: Vue.js 是一个轻量级的前端JavaScript框架,用于构建用户界面。Vue的特点包括声明式渲染、组件化、虚拟DOM和响应式...

    SpringCloud集成Oauth2.0看完这个基本就理解原理了

    SpringCloud集成Oauth2.0看完这个基本就理解原理了

    spring cloud + vue + oAuth2.0全家桶实战

    在本项目中,通过集成Spring Security OAuth2,我们可以实现用户的认证和授权流程。用户可以通过微信等第三方账号登录,简化注册和登录步骤,提升用户体验。同时,OAuth2.0的令牌(Token)机制确保了数据传输的安全...

    SpringCloud 基于SpringCloud2.1的微服务开发脚手架,整合了spring-security-oauth2、nacos、feign、sent

    基于SpringCloud2.1的微服务开发脚手架,整合了spring-security-oauth2、nacos、feign、sentinel、springcloud-gateway等。服务治理方面引入elasticsearch、skywalking、springboot-admin、zipkin等,让项目开发快速...

Global site tag (gtag.js) - Google Analytics