赞
踩
springcloud Security oauth2.0认证授权实战一(获取授权码,通过授权码获取令牌)
创建父项目
sca-cloud-parent
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.hc</groupId> <artifactId>sca-cloud-parent</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <name>sca-cloud-parent</name> <modules> <module>auth-service</module> </modules> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot-admin.version>2.1.5</spring-boot-admin.version> <spring-cloud.version>Greenwich.SR2</spring-cloud.version> <spring-cloud-alibaba.version>0.9.0.RELEASE</spring-cloud-alibaba.version> </properties> <dependencies> <!-- 健康检查actuator --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- test --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <!-- spring-boot-admin --> <dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-dependencies</artifactId> <version>${spring-boot-admin.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- spring cloud --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- spring cloud alibaba --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
创建公共项目
sca-common
pom.xml 公共项目暂时没有任何东西
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>sca-cloud-parent</artifactId> <groupId>com.hc</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>sca-common</artifactId> <name>sca-common</name> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.20</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.1.2</version> </dependency> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.8.Final</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.59</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.9</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>${commons-lang3.version}</version> </dependency> <!--mybatis plus generator 自动生成代码--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.1.2</version> </dependency> <!--自动生成代码 模板引擎--> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.29</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
创建子项目
sca-auth
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>sca-cloud-parent</artifactId> <groupId>com.hc</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>auth-service</artifactId> <name>auth-service</name> <description>授权模块</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</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> <!--jwt--> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-jwt</artifactId> <version>1.0.10.RELEASE</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.12</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>com.hc</groupId> <artifactId>sca-common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
启动类
@SpringBootApplication
public class AuthServiceApplication {
public static void main(String[] args){
SpringApplication.run(AuthServiceApplication.class);
}
}
创建config包
创建认证配置类AuthorizationServerConfiguration
package com.hc.auth.config; import org.springframework.beans.factory.annotation.Autowired; 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.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.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.code.AuthorizationCodeServices; import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; import org.springframework.security.oauth2.provider.token.DefaultTokenServices; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore; /** * 认证服务配置 * @EnableAuthorizationServer 注解用于配置 OAuth 2.0 授权服务器机制, * 以及实现 AuthorizationServerConfigurer的任何 @Beans (有一个使用空方法的方便的适配器实现)。 * 以下功能委托给由 Spring 创建并传递给 AuthorizationServerConfigurer 的独立配置器 */ @Configuration @EnableAuthorizationServer public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { @Autowired private AuthorizationCodeServices authorizationCodeServices; @Autowired private BCryptPasswordEncoder passwordEncoder; @Autowired private AuthenticationManager authenticationManager; @Autowired private ClientDetailsService clientDetailsService; @Autowired private RedisConnectionFactory redisconnectionFactory; /** * 定义令牌端点上的安全约束,不是所有的请求都可以来获取令牌的 * @param security * @throws Exception */ @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { security .tokenKeyAccess("permitAll()") // 开启/oauth/token_key验证端口无权限访问 .checkTokenAccess("permitAll()") //"isAuthenticated()" // 开启/oauth/check_token验证端口认证权限访问 .passwordEncoder(passwordEncoder) .allowFormAuthenticationForClients();//允许表单认证 } /** * 定义客户端详细信息服务的配置器。客户详细信息可以初始化,或者可以引用现有的 store * 将ClientDetailsServiceConfigurer(从您的回调AuthorizationServerConfigurer)可以用来在内存或JDBC实现客户的细节服务来定义的。 * 客户端的重要属性是 * clientId:(必需)客户端ID。 * secret:(可信客户端需要)客户端密钥(如果有)。 * scope:客户受限的范围。如果范围未定义或为空(默认值),则客户端不受范围限制。 * authorizedGrantTypes:授权客户端使用的授权类型。默认值为空。 * authorities:授予客户端的权限(常规Spring Security权限)。 * 客户端详细信息可通过直接访问底层存储(例如 JdbcClientDetailsService 用例中的数据库表)或者通过 ClientDetailsManager 接口(ClientDetailsService 也能实现这两种实现),可以在正在运行的应用程序中更新客户端详细信息。 * @param clients * @throws Exception */ @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory()//配置在内存里,后面修改为数据库里 //~============== 注册【客户端应用】,使客户端应用能够访问认证服务器 =========== .withClient("sca_app")//客户端id .secret(passwordEncoder.encode("secret_key")) //客户端密钥 .scopes("all","read","write") //sca_app有哪些权限 .accessTokenValiditySeconds(3600) //token的有效期 .resourceIds("system-service") //资源服务器的id。发给sca_app的token,能访问哪些资源服务器,可以多个 .authorizedGrantTypes("authorization_code","password","client_creentials","implicit","refresh_token")//授权方式,再给orderApp做授权的时候可以用哪种授权方式授权 //.autoApprove(false) // false 跳转到授权页面 .redirectUris("http://www.baidu.com");// 加上验证回调地址 //~=============客户端应用配置结束 ===================== } /** * /oauth/authorize 授权端点 * /oauth/token 令牌断点 * /oauth/confirm-access用户确认授权提交端点 * /auth/error 授权服务错误信息断电 * /auth/check_token 用户资源服务访问的令牌解析断电 * /oauth/token_key 提供公有密钥的端点,如果你使用jwt令牌的话 */
yml
server: port: 7000 spring: profiles: active: dev cloud: nacos: discovery: #注册中心 server-addr: 127.0.0.1:8848 redis: #redis配置 host: 192.168.1.101 port: 6379 password: 123456 datasource: #数据源 driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/rytmp?useSSL=false&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8 username: root password: 123456 druid: initialSize: 5 #初始化连接大小 minIdle: 5 #最小连接池数量 maxActive: 20 #最大连接池数量 maxWait: 60000 #获取连接时最大等待时间,单位毫秒 timeBetweenEvictionRunsMillis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 minEvictableIdleTimeMillis: 300000 #配置一个连接在池中最小生存的时间,单位是毫秒 validationQuery: SELECT 1 from DUAL #测试连接 testWhileIdle: true #申请连接的时候检测,建议配置为true,不影响性能,并且保证安全性 testOnBorrow: false #获取连接时执行检测,建议关闭,影响性能 testOnReturn: false #归还连接时执行检测,建议关闭,影响性能 poolPreparedStatements: false #是否开启PSCache,PSCache对支持游标的数据库性能提升巨大,oracle建议开启,mysql下建议关闭 maxPoolPreparedStatementPerConnectionSize: 20 #开启poolPreparedStatements后生效 filters: stat,wall,log4j #配置扩展插件,常用的插件有=>stat:监控统计 log4j:日志 wall:防御sql注入 connectionProperties: 'druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000' #通过connectProperties属性来打开mergeSql功能;慢SQL记录 mybatis-plus: mapper-locations: classpath*:mapper/*.xml feign: sentinel: enabled: true client: config: default: #default默认所有服务的超时时间 connect-timeout: 10000 read-timeout: 20000 # payment-service: #指定payment-service这个服务的超时时间 # connect-timeout: 10000 # read-timeout: 20000 auth-service: #指定payment-service这个服务的负载策略,也可以不用这一级,直接下面的配置 代表所有 ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #配置规则 随机 #NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule #配置规则 轮询 #NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RetryRule #配置规则 重试 #NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule #配置规则 响应时间权重 #NFLoadBalancerRuleClassName: com.netflix.loadbalancer.BestAvailableRule #配置规则 最空闲连接策略 ConnectTimeout: 500 #请求连接超时时间 ReadTimeout: 1000 #请求处理的超时时间 OkToRetryOnAllOperations: true #对所有请求都进行重试 MaxAutoRetriesNextServer: 2 #切换实例的重试次数 MaxAutoRetries: 1 #对当前实例的重试次数
WebSecurityConfiguration
package com.hc.auth.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 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; /** * web访问安全策略配置 */ @Configuration @EnableWebSecurity public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { //配置加密方式 @Bean public BCryptPasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } //认证管理器 @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } /** * 配置用户信息 * @param auth * @throws Exception */ @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //这里暂时使用内存方式来保存用户信息,后期从数据库中读取 auth.inMemoryAuthentication() .withUser("user1").password(passwordEncoder().encode("123456")).roles("admin") .and() .withUser("user2").password(passwordEncoder().encode("123456")).roles("tourist"); } }
首先我们要知道客户端用来从最终用户获取访问令牌的授权类型(例如,授权码,用户凭证,刷新令牌)
测试
一.授权码模式测试
1,获取授权码 code
这里有两个参数client_id这是客户端信息里面配置的,response_type访问授权类型就是code 授权码
http://localhost:7000/oauth/authorize?client_id=sca_app&response_type=code
两个参数不行就用下面的
http://localhost:7000/oauth/authorize?response_type=code&client_id=sca_app&scope=all&redirect_uri=http://www.baidu.com
会跳到登录页面
输入用户名密码,通过授权
2,使用code换取令牌token
校验token
二.密码模式
校验token
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。