SpringCloud-OAuth2.0-JWT 认证授权(授权码模式)

OAuth2.0提供了四种授权模式
,refresh_token, 是否刷新token
授权码模式 authorization_code
密码模式 password
简化模式 implicit
客户端模式 client_credentials

此案例目前完成授权码模式,其他模式还没测试,后续会完善
学习笔记,直接上代码了
创建springboot项目,引入基本的依赖,mysql,mybatis,以及自动生成代码jar
springcloud版本 <spring-cloud.version>Greenwich.BUILD-SNAPSHOT</spring-cloud.version>
1. pom文件核心依赖

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-oauth2</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-security</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-jwt</artifactId>
			<version>1.0.10.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.generator</groupId>
			<artifactId>mybatis-generator-core</artifactId>
			<version>1.3.5</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.2</version>
		</dependency>

	</dependencies>

2.首先看spring-security的配置类

package com.youdu.distributed.authentication.config;
import com.youdu.distributed.authentication.service.UserServiceDetail;
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.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import javax.servlet.http.HttpServletResponse;

/**
 * @author Sir_小三
 * @date 2020/1/30--13:01
 * AuthorizationServer认证服务配置
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	//使用密码模式,必须要配置)
	@Autowired
	private UserServiceDetail userServiceDetail;

	/**
	 * 	//配置认证管理器(使用密码模式,必须要配置)
	 * 	但是目前配置此bean,登陆,直接栈溢出error,还没解决
	 * @return
	 */
	@Override
	@Bean
	public AuthenticationManager authenticationManager() throws Exception{
		return super.authenticationManagerBean();
	}

	//密码编码器
	@Bean
	public PasswordEncoder passwordEncoder(){
		return new BCryptPasswordEncoder();
	}

	/**
	 * 所有请求都必须经过认证
	 * @param http
	 * @throws Exception
	 */
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http
				.csrf().disable()
//				.exceptionHandling()
//				.authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
//				.and()
				.authorizeRequests()
				.anyRequest()
				.authenticated()
				.and()
				.formLogin();//表单提交方式
				//.successForwardUrl("/login/success");//登陆成功以后的controller
				//.httpBasic(); 远程调用Basic方式,
	}

	/**
	 * 认证用户名密码
	 * @param auth
	 * @throws Exception
	 */
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(userServiceDetail).passwordEncoder(passwordEncoder());
//		auth.inMemoryAuthentication()//内存方式
//                .passwordEncoder(passwordEncoder()) // 指定加密方式
//                .withUser("lyj").password(passwordEncoder().encode("123456")).roles("ADMIN");
	}
}

3.认证服务的配置类

package com.youdu.distributed.authentication.config;

import com.youdu.distributed.authentication.service.UserServiceDetail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
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.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.token.*;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;

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

/**
 * @author Sir_小三
 * @date 2020/1/30--14:01
 * AuthorizationServer认证服务配置
 */
@Configuration
@EnableAuthorizationServer//开启认证服务/oauth/authorize,/oauth/token,/oauth/check_token,/oauth/confirm_access,/oauth/error
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
//    @Autowired
//    private AuthenticationManager authenticationManager;
    @Autowired
    private TokenStore tokenStore;
    @Autowired
    private AuthorizationCodeServices authorizationCodeServices;

    @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private DataSource dataSource;
//    @Autowired
//    private UserServiceDetail userServiceDetail;
    /**
     * 配置令牌访问端点得安全约束
     * 必须设置allowFormAuthenticationForClients 否则没有办法用postman获取token
     * 也需要指定密码加密方式BCryptPasswordEncoder
     *
     */

    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.tokenKeyAccess("permitAll()") //公开获取token的url
                .checkTokenAccess("permitAll()")//校验token的合法性
                .allowFormAuthenticationForClients();
                //.passwordEncoder(NoOpPasswordEncoder.getInstance());//不需要加密

    }

    /**
     * //配置客户端详情,客户端详情可以通过数据库查询,(校验哪些客户端可以申请令牌)
     * clientid 客户端id
     * secret 客户端安全码
     * scope 用来限制客户端得访问范围,默认为空,如果为空,那么客户端拥有全部得访问范围
     * authorizedGrantTypes  此客户端可以使用得授权类型,默认为空,oauth2提供了五种授权类型
     * authorities 此客户端可以使用 得权限  基于spring security authorities(一般不使用)
     *
     * @param clients
     * @throws Exception
     * 这里客户端信息存在数据库
     */
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.withClientDetails(clientDetailsService());//配置客户端信息
        //内存方式配置
//        clients.inMemory().withClient("resources-service")//客户端id
//                .secret(passwordEncoder.encode("123456"))//客户端密钥,需要加密,使用数据库存,数据库的要经过加密处理
//                .resourceIds("res1")//资源id
//                .authorizedGrantTypes("authorization_code","refresh_token","password")//oauth2 四种授权类型,目前两种,授权码,密码模式
//                .scopes("all")
//                .autoApprove(false)//授权码模式,false会跳转到授权页面,让用户授权,true不跳
//                .redirectUris("http://www.baidu.com")//授权码模式,回调地址
//                .accessTokenValiditySeconds(3600);
    }

    /**
     * 配置令牌访问端点url,和令牌服务(令牌生成策略,如何生成)
     * /oauth/authorize   授权端点
     * 获取授权码
     * http://localhost:8762/oauth/authorize?response_type=code&client_id=resources-service&scope=all&client_secret=123456&redirect_uri=http://www.baidu.com
     * /oauth/token       获取令牌端点(发送post请求,获取token,code=申请的授权码)
     *
     * /oauth/confirm_access  用户确认授权端点
     * /oauth/error  授权服务错误信息端点
     * /oauth/check_token  用于资源服务访问的令牌解析端点
     * /oauth/token_key  提供公有密钥的端点,如果使用jwt令牌的话
     * 授权端点url应该被spring-security 保护起来,只供授权用户访问
     * @param endpoints
     * @throws Exception
     */
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                //.authenticationManager(authenticationManager)//认证管理服务,密码模式必须配置,还有userServiceDetail
                .authorizationCodeServices(authorizationCodeServices)//授权码模式
                .tokenStore(tokenStore)
                //在这里设置jwtAccessTokenConverter,发现是ok的,可以生成jwt令牌
                .accessTokenConverter(jwtAccessTokenConverter)
                //.userDetailsService(userServiceDetail)//密码模式要配
                .allowedTokenEndpointRequestMethods(HttpMethod.POST);
    }

    //令牌管理服务
    @Bean
    public AuthorizationServerTokenServices tokenServices() {
        DefaultTokenServices service = new DefaultTokenServices();
        service.setClientDetailsService(clientDetailsService());//客户端详情服务`ervice.setSupportRefreshToken(true);//支持刷新令牌-*
        service.setTokenStore(tokenStore);//令牌存储策略
        //令牌增强,使用jwt令牌
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        //在这里设置jwtAccessTokenConverter,但是发现不起作用,令牌还是普通令牌,加到发现可以
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(jwtAccessTokenConverter));
        service.setTokenEnhancer(tokenEnhancerChain);
        service.setSupportRefreshToken(true);  //支持刷新令牌
        service.setAccessTokenValiditySeconds(7200);//令牌默认有效两小时
        service.setRefreshTokenValiditySeconds(259200);//刷新令牌默认有效期三天
        return service;

    }

    //设置授权码模式的授权码如何存取
    @Bean
    public AuthorizationCodeServices authorizationCodeServices(DataSource dataSource){
        return new JdbcAuthorizationCodeServices(dataSource);
    }
    //内存方式存储授权码
//    @Bean
//    public AuthorizationCodeServices authorizationCodeServices(){
//        return new InMemoryAuthorizationCodeServices();
//    }

    /**
     * 客户端配置从数据库读取,发起授权时,会查询数据库数据进行认证,可添加n条客户端数据,获取验证码
     * 客户端拿到验证码,请求/oauth/token,获取令牌,
     * 注意!!!数据库中存储客户端密钥,需要使用BCryptPasswordEncoder加密后,在存,
     * 不然获取token的时候会报错(说不是BCryptPasswordEncoder格式)
     *  (应该是将你请求的密钥123456经过加密,和数据库中的数据做比对,ok,则发送令牌)
     *  获取token需要的参数
     *  "client_id":"r1",
     *  "client_secret":"123456",
     *  "grant_type":"authorization_code",
     *  "scope":"all",
     *  "redirect_uri":"http://www.baidu.com",
     *  "code":"5AsJkQ",
     * @return
     */
    @Bean
    public ClientDetailsService clientDetailsService(){
        JdbcClientDetailsService jdbcClientDetailsService = new JdbcClientDetailsService(dataSource);
        jdbcClientDetailsService.setPasswordEncoder(passwordEncoder);
        return  jdbcClientDetailsService;
    }
}

4.JwtTokenConfig 配置类,暂时使用对称加密

package com.youdu.distributed.authentication.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

/**
 * @author Sir_小三
 * @date 2020/1/30--14:34
 */

@Configuration
public class TokenConfig {
    //对称加密,密钥,也可采用非对称加密
    private  String SIGNING_KRY="lyj123";

    /**
     * 使用密钥生成令牌
     * @return
     */
    @Bean
    public JwtAccessTokenConverter accessTokenConverter(){
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey(SIGNING_KRY);
        return converter;
    }

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

    //内存存储简单令牌
//        @Bean
//    public TokenStore tokenStore() {
//        return new InMemoryTokenStore();
//    }

}

5.还有一个重要的,UserServiceDetail 配置
这里SecurityUser 去继承security.core.userdetails.User提供的user
此类来验证登陆用户密码

package com.youdu.distributed.authentication.service;

import com.youdu.distributed.authentication.entity.SecurityUser;
import com.youdu.distributed.authentication.entity.TbUser;
import com.youdu.distributed.authentication.mapper.TbUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
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 Sir_小三
 * @date 2020/1/30--12:54
 */
@Service
public class UserServiceDetail implements UserDetailsService {

    @Autowired
    private TbUserMapper tbUserMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        TbUser tbUser = new TbUser();
        tbUser.setName(username);
        List<TbUser> page = tbUserMapper.page(tbUser, null);
        TbUser tbUser1 = page.get(0);
        SecurityUser securityUser = new SecurityUser(username, tbUser1.getPassword(),grantedAuthorities);
        return securityUser;
    }
}

package com.youdu.distributed.authentication.entity;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;

import java.util.Collection;

/**
 * @author Sir_小三
 * @date 2020/1/30--18:56
 */
public class SecurityUser extends User {

    public SecurityUser(String username, String password, Collection<? extends GrantedAuthority> authorities) {
        super(username, password, authorities);
    }

    public SecurityUser(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
        super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
    }
}

6.到这里重要代码基本就贴完了,剩下的就没什么了,贴一下配置文件,主要就eureka地址,以及mysql连接

#client每30秒会发送心跳给eureka进行续约,如果eureka90秒没有收到客户端心跳,那么注册中心会剔除此client
#client注册到eureka时,会将自己的ip地址等信息进行提供,eureka会存所有客户端的注册信息表,client会将其获取到本地内存,进行调用
server.port:8762
#需要指明spring.application.name,这个很重要,这在以后的服务与服务之间相互调用一般都是根据这个name 。
spring.application.name=distributed-authentication
#指定erreka-server注册中心的地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
#开启feign断路器熔断机制,Feign是自带断路器的,在D版本的Spring Cloud之后,它没有默认打开。需要在配置文件中配置打开它
#feign.hystrix.enabled=true
#指定链路跟踪地址zipkin server
#spring.zipkin.base-url=http://localhost:9411

#调用的超时时间   springcloud默认情况下一秒之内调用成功,否则将打开断路器
#hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.url=jdbc:mysql://localhost:3306/rootdatabase?useUnicode=true&characterEncoding=utf-8&useSSL=false
#spring.datasource.username=root
#spring.datasource.password=123456
mybatis.mapper-locations=classpath:mapper/*.xml
#tx-lcn.client.manager-address=127.0.0.1:8070    tc默认连接tm的ip端口
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/oauth2?useUnicode=true&characterEncoding=utf-8&useLegacyDatetimeCode=false&serverTimezone=PRC
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.main.allow-bean-definition-overriding=true

7.提供一下oauth2的数据库表,这都是由oauth2提供的,直接运行生成表即可

CREATE SCHEMA IF NOT EXISTS `oauth2` DEFAULT CHARACTER SET utf8 ;
USE `oauth2` ;
 
-- -----------------------------------------------------
-- Table `oauth2`.`clientdetails`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `oauth2`.`clientdetails` (
  `appId` VARCHAR(128) NOT NULL,
  `resourceIds` VARCHAR(256) NULL DEFAULT NULL,
  `appSecret` VARCHAR(256) NULL DEFAULT NULL,
  `scope` VARCHAR(256) NULL DEFAULT NULL,
  `grantTypes` VARCHAR(256) NULL DEFAULT NULL,
  `redirectUrl` VARCHAR(256) NULL DEFAULT NULL,
  `authorities` VARCHAR(256) NULL DEFAULT NULL,
  `access_token_validity` INT(11) NULL DEFAULT NULL,
  `refresh_token_validity` INT(11) NULL DEFAULT NULL,
  `additionalInformation` VARCHAR(4096) NULL DEFAULT NULL,
  `autoApproveScopes` VARCHAR(256) NULL DEFAULT NULL,
  PRIMARY KEY (`appId`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
 
 
-- -----------------------------------------------------
-- Table `oatuh2`.`oauth_access_token`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `oauth2`.`oauth_access_token` (
  `token_id` VARCHAR(256) NULL DEFAULT NULL,
  `token` BLOB NULL DEFAULT NULL,
  `authentication_id` VARCHAR(128) NOT NULL,
  `user_name` VARCHAR(256) NULL DEFAULT NULL,
  `client_id` VARCHAR(256) NULL DEFAULT NULL,
  `authentication` BLOB NULL DEFAULT NULL,
  `refresh_token` VARCHAR(256) NULL DEFAULT NULL,
  PRIMARY KEY (`authentication_id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
 
 
-- -----------------------------------------------------
-- Table `oatuh2`.`oauth_approvals`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `oauth2`.`oauth_approvals` (
  `userId` VARCHAR(256) NULL DEFAULT NULL,
  `clientId` VARCHAR(256) NULL DEFAULT NULL,
  `scope` VARCHAR(256) NULL DEFAULT NULL,
  `status` VARCHAR(10) NULL DEFAULT NULL,
  `expiresAt` DATETIME NULL DEFAULT NULL,
  `lastModifiedAt` DATETIME NULL DEFAULT NULL)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
 
 
-- -----------------------------------------------------
-- Table `oatuh2`.`oauth_client_details`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `oauth2`.`oauth_client_details` (
  `client_id` VARCHAR(128) NOT NULL,
  `resource_ids` VARCHAR(256) NULL DEFAULT NULL,
  `client_secret` VARCHAR(256) NULL DEFAULT NULL,
  `scope` VARCHAR(256) NULL DEFAULT NULL,
  `authorized_grant_types` VARCHAR(256) NULL DEFAULT NULL,
  `web_server_redirect_uri` VARCHAR(256) NULL DEFAULT NULL,
  `authorities` VARCHAR(256) NULL DEFAULT NULL,
  `access_token_validity` INT(11) NULL DEFAULT NULL,
  `refresh_token_validity` INT(11) NULL DEFAULT NULL,
  `additional_information` VARCHAR(4096) NULL DEFAULT NULL,
  `autoapprove` VARCHAR(256) NULL DEFAULT NULL,
  PRIMARY KEY (`client_id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
 
 
-- -----------------------------------------------------
-- Table `oatuh2`.`oauth_client_token`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `oauth2`.`oauth_client_token` (
  `token_id` VARCHAR(256) NULL DEFAULT NULL,
  `token` BLOB NULL DEFAULT NULL,
  `authentication_id` VARCHAR(128) NOT NULL,
  `user_name` VARCHAR(256) NULL DEFAULT NULL,
  `client_id` VARCHAR(256) NULL DEFAULT NULL,
  PRIMARY KEY (`authentication_id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
 
 
-- -----------------------------------------------------
-- Table `oatuh2`.`oauth_code`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `oauth2`.`oauth_code` (
  `code` VARCHAR(256) NULL DEFAULT NULL,
  `authentication` BLOB NULL DEFAULT NULL)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
 
 
-- -----------------------------------------------------
-- Table `oatuh2`.`oauth_refresh_token`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `oauth2`.`oauth_refresh_token` (
  `token_id` VARCHAR(256) NULL DEFAULT NULL,
  `token` BLOB NULL DEFAULT NULL,
  `authentication` BLOB NULL DEFAULT NULL)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

8.获取授权码url参考
首先发送这个请求,参数要换成自己的,由于spring-security的配置,所有请求必须认证通过,所以会跳至spring-security提供的登陆进行认证,登陆成功,还需认证客户端参数,是否于数据库配置一样,一样,则返回授权页面,进行授权,用户点击授权,跳转到指定url,并发放授权码,
拿到授权码,认证服务器会将授权码存在数据库,一个授权码只能申请一次令牌
接下来,使用授权码获取jwt令牌

http://localhost:8762/oauth/authorize?response_type=code&client_id=resources-service&scope=all&client_secret=123456&redirect_uri=http://www.baidu.com

在这里插入图片描述

获取到code图片
在这里插入图片描述

9.获取到授权码,postman通过获取的授权码,申请jwt令牌

在这里插入图片描述

10.校验令牌

在这里插入图片描述
通过令牌访问资源服务器
在这里插入图片描述

11.以后客户端拿令牌,访问资源服务,目前资源服务还没做好,做好后期会更新,还要密码授权模式,也没搞清除,感觉密码模式加jwt可以做分布式的单点登陆,后续有时间会更新的,有不清除的或者想要源码的,可加我微信,xiaosang953038659,谢谢你看到最后,嘻嘻

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 前后端分离是一种将前端界面与后端逻辑进行分离开发的架构方式,使得前端与后端可以并行开发。OAuth 2.0是一种授权框架,用于授权认证流程的规范化,而Spring Security是一个在Java中实现安全控制的框架,提供了大量的安全特性。Spring Authorization Server是Spring Security中用于实现授权服务器的模块,它支持OAuth 2.0的各种授权模式。 密模式是OAuth 2.0中的一种授权模式,它允许用户通过提交用户名和密来获取访问令牌,然后使用该令牌来访问受保护的资源。在前后端分离的架构中,可以使用Spring Security配合Spring Authorization Server来实现密模式认证授权。 在密模式下,前端首先需要收集用户的用户名和密,并将其发送给后端。后端使用Spring Security提供的密器对密进行加密,并验证用户名和密的正确性。如果验证通过,则后端向客户端颁发一个访问令牌,通常是一个JWT(JSON Web Token)。前端使用获得的访问令牌来访问需要受保护的资源,每次请求将该令牌作为Authorization头的Bearer字段发送给后端进行验证。后端可以使用Spring Security的资源服务器来验证该令牌的有效性,并根据用户的权限控制对资源的访问。 使用Spring Security和Spring Authorization Server的密模式可以实现安全的前后端分离架构。通过合理配置和使用安全特性,可以保障用户的身份认证和资源的授权,确保系统的安全性。 ### 回答2: 前后端分离是一种软件架构模式,前端和后端通过使用API进行通信,分别负责处理用户界面和数据逻辑。OAuth 2.0是一种用于授权的开放标准协议,它允许用户在第三方应用程序中授权访问其受保护的资源。Spring Security是Spring框架中的一个模块,提供了身份验证和授权功能。 在前后端分离的架构中,前端应用程序通常需要使用OAuth 2.0协议进行用户授权,以访问后端应用程序的受保护资源。为了实现密模式,我们可以使用Spring Security的模块之一,即spring-authorization-server。 spring-authorization-server是Spring Security的一个子模块,用于实现OAuth 2.0协议中的授权服务器。密模式是OAuth 2.0协议中的一种授权模式,允许前端应用程序通过用户的用户名和密进行授权。密模式在安全性上有一定的风险,因此在实际应用中需要谨慎使用。 使用spring-authorization-server的密模式,我们可以在前端应用程序中收集用户的用户名和密,并将其提交给后端应用程序进行验证。后端应用程序将使用Spring Security进行身份验证,并向前端应用程序颁发一个访问令牌,该令牌可以用于后续的API请求。 通过使用前后端分离、OAuth 2.0和spring-authorization-server的密模式,我们可以实现安全的用户授权和身份验证机制,确保只有经过授权的用户才能访问受保护的资源。这种架构模式能够提高系统的安全性和可扩展性,适用于各种类型的应用程序。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值