范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

SpringCloud整合springsecurityoauth2Redis实现认证授权

  设置通用父工程依赖
  在微服务构建中,我们一般用一个父工程来通知管理依赖的各种版本号信息。父工程pom文件如下:
  <?xml version="1.0" encoding="UTF-8"?>
  
  4.0.0
  com.zjq
  oauth2-demo
  pom
  1.0-SNAPSHOT
  commons
  ms-gateway
  ms-oauth2-server
  ms-registry
  
  2.3.7.RELEASE
  Hoxton.SR9
  1.18.16
  3.11
  2.1.3
  8.0.22
  2.1.5-RELEASE
  5.4.7
  20.0
  1.8
  1.8
  UTF-8
  
  org.springframework.boot
  spring-boot-dependencies
  ${spring-boot-version}
  pom
  import
  
  org.springframework.cloud
  spring-cloud-dependencies
  ${spring-cloud-version}
  pom
  import
  
  org.projectlombok
  lombok
  ${lombok-version}
  
  org.apache.commons
  commons-lang3
  ${commons-lang-version}
  
  org.mybatis.spring.boot
  mybatis-spring-boot-starter
  ${mybatis-starter-version}
  
  com.battcn
  swagger-spring-boot-starter
  ${swagger-starter-version}
  
  mysql
  mysql-connector-java
  ${mysql-version}
  
  cn.hutool
  hutool-all
  ${hutool-version}
  
  com.google.guava
  guava
  ${guava-version}
  
  
  
  org.springframework.boot
  spring-boot-maven-plugin
  
  
  
  
  
  构建eureka注册中心
  在SpringCloud微服务体系中服务注册中心是一个必要的存在,通过注册中心提供服务的注册和发现。具体细节可以查看我之前的博客,这里不再赘述。我们开始构建一个eureka注册中心,对应的yml配置文件如下:
  server:
  port: 8080
  spring:
  application:
  # 应用名称
  name: ms-registry
  # 配置 Eureka Server 注册中心
  eureka:
  client:
  register-with-eureka: false
  fetch-registry: false
  service-url:
  defaultZone: http://localhost:8080/eureka/
  logging:
  pattern:
  console: "%d{HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n"
  对应的项目启动类代码如下:
  package com.zjq.msregistry;
  import org.springframework.boot.SpringApplication;
  import org.springframework.boot.autoconfigure.SpringBootApplication;
  import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
  /**
  * 注册中心
  * @author zjq
  */
  //启动 eureka注册中心服务端相关组件
  @EnableEurekaServer
  @SpringBootApplication
  public class MsRegistryApplication {
  public static void main(String[] args) {
  SpringApplication.run(MsRegistryApplication.class, args);
  }
  }
  至此,一个单体的服务注册中心搭建完成。
  构建认证授权服务
  上文我们已经完成了注册中心的搭建,接下来我们开始搭建认证授权中心。
  配置文件设置
  我们同样在父工程下面新建一个子工程,作为认证授权中心的微服务。对应的yml文件和pom文件配置如下:
  application.yml
  server:
  port: 8082 # 端口
  spring:
  application:
  name: ms-oauth2-server # 应用名
  # 数据库
  datasource:
  driver-class-name: com.mysql.cj.jdbc.Driver
  username: root
  password: 123456
  url: jdbc:mysql://127.0.0.1:3306/oauth2?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false
  # Redis
  redis:
  port: 6379
  host: localhost
  timeout: 3000
  database: 1
  password: 123456
  # swagger
  swagger:
  base-package: com.zjq.oauth2
  title: 认证服务API接口文档
  # Oauth2
  client:
  oauth2:
  client-id: appId # 客户端标识 ID
  secret: 123456 # 客户端安全码
  # 授权类型
  grant_types:
  - password
  - refresh_token
  # token 有效时间,单位秒
  token-validity-time: 3600
  refresh-token-validity-time: 3600
  # 客户端访问范围
  scopes:
  - api
  - all
  # 配置 Eureka Server 注册中心
  eureka:
  instance:
  prefer-ip-address: true
  instance-id: ${spring.cloud.client.ip-address}:${server.port}
  client:
  service-url:
  defaultZone: http://localhost:8080/eureka/
  # Mybatis
  mybatis:
  configuration:
  map-underscore-to-camel-case: true # 开启驼峰映射
  # 指标监控健康检查
  management:
  endpoints:
  web:
  exposure:
  include: "*" # 暴露的端点
  logging:
  pattern:
  pom.xml
  <?xml version="1.0" encoding="UTF-8"?>
  
  oauth2-demo
  com.zjq
  1.0-SNAPSHOT
  
  4.0.0
  ms-oauth2-server
  org.springframework.cloud
  spring-cloud-starter-netflix-eureka-client
  
  org.springframework.boot
  spring-boot-starter-web
  
  org.springframework.boot
  spring-boot-starter-data-redis
  
  org.mybatis.spring.boot
  mybatis-spring-boot-starter
  
  mysql
  mysql-connector-java
  
  org.springframework.cloud
  spring-cloud-starter-security
  
  org.springframework.cloud
  spring-cloud-starter-oauth2
  
  com.zjq
  commons
  1.0-SNAPSHOT
  
  org.springframework.boot
  spring-boot-configuration-processor
  true
  
  
  
  Security配置类
  我们开始搭建Spring Security相关的配置类,具体配置类代码如下:
  package com.zjq.oauth2.server.config;
  import cn.hutool.crypto.digest.DigestUtil;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.data.redis.connection.RedisConnectionFactory;
  import org.springframework.security.authentication.AuthenticationManager;
  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.password.PasswordEncoder;
  import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
  import javax.annotation.Resource;
  /**
  * Security 配置类
  * @author zjq
  */
  @Configuration
  @EnableWebSecurity
  public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  // 注入 Redis 连接工厂
  @Resource
  private RedisConnectionFactory redisConnectionFactory;
  /**
  * 初始化 RedisTokenStore 用于将 token 存储至 Redis
  * @return
  */
  @Bean
  public RedisTokenStore redisTokenStore() {
  RedisTokenStore redisTokenStore = new RedisTokenStore(redisConnectionFactory);
  redisTokenStore.setPrefix("TOKEN:"); // 设置key的层级前缀,方便查询
  return redisTokenStore;
  }
  // 初始化密码编码器,用 MD5 加密密码
  @Bean
  public PasswordEncoder passwordEncoder() {
  return new PasswordEncoder() {
  /**
  * 加密
  * @param rawPassword 原始密码
  * @return
  */
  @Override
  public String encode(CharSequence rawPassword) {
  return DigestUtil.md5Hex(rawPassword.toString());
  }
  /**
  * 校验密码
  * @param rawPassword 原始密码
  * @param encodedPassword 加密密码
  * @return
  */
  @Override
  public boolean matches(CharSequence rawPassword, String encodedPassword) {
  return DigestUtil.md5Hex(rawPassword.toString()).equals(encodedPassword);
  }
  };
  }
  // 初始化认证管理对象
  @Bean
  @Override
  public AuthenticationManager authenticationManagerBean() throws Exception {
  return super.authenticationManagerBean();
  }
  // 放行和认证规则
  @Override
  protected void configure(HttpSecurity http) throws Exception {
  http.csrf().disable()
  .authorizeRequests()
  // 放行的请求
  .antMatchers("/oauth/**", "/actuator/**").permitAll()
  .and()
  .authorizeRequests()
  // 其他请求必须认证才能访问
  .anyRequest().authenticated();
  }
  }
  Security配置类主要完成以下配置:
  注入 Redis 连接工厂
  初始化 RedisTokenStore 用于将 token 存储至 Redis
  初始化密码编码器,用 MD5 加密密码
  初始化认证管理对象
  设置放行和认证规则
  授权服务配置类
  配置完了security配置类后,我们开始编写授权服务配置类,授权服务配置类需要继承AuthorizationServerConfigurerAdapter并重写对应的方法,tips:idea子类重写父类快捷键是Ctrl+O,重写后的授权服务配置类如下:
  package com.zjq.oauth2.server.config;
  import com.zjq.commons.model.domain.SignInIdentity;
  import com.zjq.oauth2.server.service.UserService;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.security.authentication.AuthenticationManager;
  import org.springframework.security.crypto.password.PasswordEncoder;
  import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
  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.token.store.redis.RedisTokenStore;
  import javax.annotation.Resource;
  import java.util.LinkedHashMap;
  /**
  * 授权服务配置类
  * @author zjq
  */
  @Configuration
  @EnableAuthorizationServer
  public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
  // RedisTokenSore
  @Resource
  private RedisTokenStore redisTokenStore;
  // 认证管理对象
  @Resource
  private AuthenticationManager authenticationManager;
  // 密码编码器
  @Resource
  private PasswordEncoder passwordEncoder;
  // 客户端配置类
  @Resource
  private ClientOAuth2DataConfiguration clientOAuth2DataConfiguration;
  // 登录校验
  @Resource
  private UserService userService;
  /**
  * 配置令牌端点安全约束
  *
  * @param security
  * @throws Exception
  */
  @Override
  public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
  // 允许访问 token 的公钥,默认 /oauth/token_key 是受保护的
  security.tokenKeyAccess("permitAll()")
  // 允许检查 token 的状态,默认 /oauth/check_token 是受保护的
  .checkTokenAccess("permitAll()");
  }
  /**
  * 客户端配置 - 授权模型
  *
  * @param clients
  * @throws Exception
  */
  @Override
  public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
  clients.inMemory().withClient(clientOAuth2DataConfiguration.getClientId()) // 客户端标识 ID
  .secret(passwordEncoder.encode(clientOAuth2DataConfiguration.getSecret())) // 客户端安全码
  .authorizedGrantTypes(clientOAuth2DataConfiguration.getGrantTypes()) // 授权类型
  .accessTokenValiditySeconds(clientOAuth2DataConfiguration.getTokenValidityTime()) // token 有效期
  .refreshTokenValiditySeconds(clientOAuth2DataConfiguration.getRefreshTokenValidityTime()) // 刷新 token 的有效期
  .scopes(clientOAuth2DataConfiguration.getScopes()); // 客户端访问范围
  }
  /**
  * 配置授权以及令牌的访问端点和令牌服务
  *
  * @param endpoints
  * @throws Exception
  */
  @Override
  public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
  // 认证器
  endpoints.authenticationManager(authenticationManager)
  // 具体登录的方法
  .userDetailsService(userService)
  // token 存储的方式:Redis
  .tokenStore(redisTokenStore);
  }
  }
  上面用到的客户端配置类如下:
  package com.zjq.oauth2.server.config;
  import lombok.Data;
  import org.springframework.boot.context.properties.ConfigurationProperties;
  import org.springframework.stereotype.Component;
  /**
  * 客户端配置类
  * @author zjq
  */
  @Component
  @ConfigurationProperties(prefix = "client.oauth2")
  @Data
  public class ClientOAuth2DataConfiguration {
  // 客户端标识 ID
  private String clientId;
  // 客户端安全码
  private String secret;
  // 授权类型
  private String[] grantTypes;
  // token有效期
  private int tokenValidityTime;
  /**
  * refresh-token有效期
  */
  private int refreshTokenValidityTime;
  /**
  * 客户端访问范围
  */
  private String[] scopes;
  }
  具体登录的方法实现:
  登录实现
  package com.zjq.oauth2.server.service;
  import com.zjq.commons.model.domain.SignInIdentity;
  import com.zjq.commons.model.pojo.Users;
  import com.zjq.commons.utils.AssertUtil;
  import com.zjq.oauth2.server.mapper.UsersMapper;
  import org.springframework.beans.BeanUtils;
  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 javax.annotation.Resource;
  /**
  * 登录校验
  * @author zjq
  */
  @Service
  public class UserService implements UserDetailsService {
  @Resource
  private UsersMapper usersMapper;
  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  AssertUtil.isNotEmpty(username, "请输入用户名");
  Users users = usersMapper.selectByAccountInfo(username);
  if (users == null) {
  throw new UsernameNotFoundException("用户名或密码错误,请重新输入");
  }
  // 初始化登录认证对象
  SignInIdentity signInIdentity = new SignInIdentity();
  // 拷贝属性
  BeanUtils.copyProperties(users, signInIdentity);
  return signInIdentity;
  }
  }
  UsersMapper:
  package com.zjq.oauth2.server.mapper;
  import com.zjq.commons.model.pojo.Users;
  import org.apache.ibatis.annotations.Param;
  import org.apache.ibatis.annotations.Select;
  /**
  * 用户 Mapper
  * @author zjq
  */
  public interface UsersMapper {
  /**
  *
  * 根据用户名 or 手机号 or 邮箱查询用户信息
  *
  * @param account
  * @return
  */
  @Select("select id, username, nickname, phone, email, " +
  "password, avatar_url, roles, is_valid from t_users where " +
  "(username = #{account} or phone = #{account} or email = #{account})")
  Users selectByAccountInfo(@Param("account") String account);
  }
  用户实体:
  package com.zjq.commons.model.pojo;
  import com.zjq.commons.model.base.BaseModel;
  import lombok.Getter;
  import lombok.Setter;
  /**
  * 用户实体类
  *
  * @Author zjq
  * @Date 2022/10/12
  */
  @Getter
  @Setter
  public class Users extends BaseModel {
  // 主键
  private Integer id;
  // 用户名
  private String username;
  // 昵称
  private String nickname;
  // 密码
  private String password;
  // 手机号
  private String phone;
  // 邮箱
  private String email;
  // 头像
  private String avatarUrl;
  // 角色
  private String roles;
  }
  package com.zjq.commons.model.base;
  import lombok.Getter;
  import lombok.Setter;
  import java.io.Serializable;
  import java.util.Date;
  /**
  * 实体对象公共属性
  *
  * @Author zjq
  * @Date 2022/10/12
  */
  @Getter
  @Setter
  public class BaseModel implements Serializable {
  private Integer id;
  private Date createDate;
  private Date updateDate;
  private int isValid;
  }
  到此,我们完成了认证授权服务构建,接下来我们进行测试验证:
  测试验证
  我们启动注册中心和认证授权微服务。访问注册中心:http://localhost:8080/
  可以看到认证授权服务已经注册到注册中心。
  接下来我们通过postman访问请求token测试:
  接下来我们通过postman访问请求token测试:
  Authorization请求头中配置,username和password,对应oauth客户端中的配置:
  在body中配置请求参数,发起请求后返回如下:
  在Redis中我们也可以看到生成的相关token配置:
  至此,我们完成了认证授权中心的初步搭建。
  ————————————————
  版权声明:本文为CSDN博主「共饮一杯无」
  原文链接:https://blog.csdn.net/qq_35427589/article/details/127340635

这是游客还是难民呀?年年有人后悔,年年还是会去,前赴后继这是游客还是难民呀???看着一群游客在老君山上冒着大雪冻的哆哩哆嗦地大口吃着泡面,我还以为这是哪里的难民呢。这两位大哥吃的是真香呀,看看这头上的雪,费了九牛二虎的力气爬上了山,腿困中国年宁德味丨城隍庙米龟沾福气民俗贺新春1月29日,大年正月初八一早,一场别具特色的米龟祈福民俗活动在宁德城隍庙里举行,吸引了不少市民游人前来祈愿。摸到头,起大楼摸到嘴,大富贵摸到尾,有头又有尾伴随着悠扬的乐声和喜庆的锣爆仓的云南,旅游革命可以休矣这个春节云南究竟来了几亿人,从昆明海埂大坝上五十人喂一只海鸥,到景洪街头涨到两千元一晚依然没有房间的如家,再到芒市把签签穿出火星的烧烤摊,连澜沧凤庆元江这些非传统旅游目的地都爆仓了盘点10种在3月盛开的花,春已暖,花欲开,你知道都有哪些吗?春天来了,万物复苏了,又到了鲜花盛开的季节了,很多朋友只知道春天花会开,但是大家知道三月份都是什么花会开吗?今天我就给大家盘点一下10种在3月份开的花,看看有没有大家喜欢的,感兴趣和我国相隔万里的高山小国,为什么张灯结彩为我们过兔年?瑞士的兔年大吉!随着中国农历新年的到来,远在欧洲的高山小国瑞士少女峰装点一新。缆车起始站早早就布置起了兔年装饰和红灯笼,冰雕区内,一只晶莹剔透的兔子前方用中文书写着兔年大吉。少女峰平遥古城游记平遥古城游记平遥古城,位于山西省晋中市平遥县,始建于周宣王时期,明洪武三年(1370年)扩建,距今已有2800多年的历史。平遥,和祁县及太古并称晋商三大故里,实为古时我国北部经济重水稻就是风景线,梯田就是金饭碗一线讲述水稻就是风景线,梯田就是金饭碗讲述人广西龙胜县龙脊镇大寨村党支部原书记潘保玉自从我们大寨村入选2022年世界最佳旅游乡村后,我的电话就响个不停,有游客来电祝贺,也有不少人取围炉享大餐长城观日出山间泡温泉,古北水镇里到处有年味无论初一暖阳初二大风,还是初三寒潮初六回暖,整个春节假期,长城脚下获评北京首批旅游度假区称号的北京密云古北水镇(司马台长城)国际旅游度假区,迎来了众多京内外游客。景区旗下酒店入住率(86)尧舜禹被孔子高度评价,他们究竟是怎样的人?今天呢,我们来讲尧舜禹的故事。先讲尧尧舜禹尧,是传说中父系氏族社会后期的部落联盟首领,原名祁放勋,后封于唐,故称陶唐氏。他代替帝挚为天子,定都平阳。在万国争雄的时代,团结周围部族,接受CT检查的阿蒙霍特普一世法老埃及,开罗原作者JARRETTA。LOBELL2023年1月2月本人仅仅增加一点内容和加以编辑整理2021年12月,埃及旅游和文物部28日说,该国研究人员运用CT扫描等技术首次以数扑朔迷离的谋杀案到底是谁杀死了塔中王子?在过去的一个半世纪里,托马斯莫尔爵士对塔中王子谋杀案的描述受到了不同程度的怀疑。尽管如此,莫尔的理查三世国王史还是值得注意的,因为它为1483年继承危机的焦点提供了精确的间接细节和
ODampamp39HORA时光馥消费者对香水产品的品鉴理解愈发独立多元作者晚乔出品明亮公司消费者的国民自信已经进入香水领域,中国市场充满活力。在香氛香水赛道逐渐火热的趋势下,一众香氛香水品牌主理人持如上观点。国内首个专业调香师品牌ODHORA时光馥创ForLoveampampampLemons品牌2019时尚广告大片MichelleGutknecht为LoveLemonsHoliday2019带来派对派对季节到了,ForLoveLemons的2019年假日活动为特殊场合季节带来了一些严肃的风格信用卡停息挂账债务重组被监管点名以信用卡反催收停息挂账债务重组为噱头招揽生意,遭到了监管的风险提示。撰文张浩东出品支付百科近年来,在街头随处可见关于信用卡反催收停息挂账债务重组的广告语,称可以帮助持卡人早日上岸。亮剑中李云龙的独立团能歼灭山崎大队吗?看过亮剑的朋友都知道,亮剑中第二场大型战斗就是李家坡之战中李云龙率领独立团全歼山崎大队。这场战斗是有历史原型的,那就是关家脑战役中八路军对抗冈崎支队。冈崎支队只有500多人,但是面有一种偷懒叫做少抱孩子更独立,专家小心孩子会变笨文菁妈01hr孩子小的时候不能总是抱他,抱他会造成依赖,以后不够独立!就多放孩子在床上躺着,让他自己玩,这样以后才能独立性更强一些。很多老人家在指导年轻人养孩子的时候,都会有这样的网约车平台运营和服务的两大基本属性什么是网约车?网络预约出租汽车运营服务企业以互联网技术为依托构建服务平台并通过网络服务平台接受约车人预约请求使用符合条件的车辆和驾驶员提供不在道路上巡游揽客站点候客的出租汽车运营服戳破了偶像天花板,刘德华的信仰,撕开了流量明星的遮羞布没想到,短短2个月时间,刘德华连续成为演艺圈焦点。先是8月中旬,犯罪电影潜行正式杀青。影片汇集了四大影帝,还有彭于晏助阵,在这些实力派演员中,刘德华位列第一男主。片中他饰演毒枭集团这才是西服的正确打开方式!学街头潮人这样穿,时髦高级又有型西服是生活中很常见的一款单品,有人将它看成凹造型的法宝,爱不释手,有人则认为西服刻板严肃,怎么穿都一本正经。会出现这一情况,主要是因为西服款式差异,或者搭配不同。在搭配上比较炉火纯健康的习惯,让你年纪越大,越健康?你想要更长寿更健康的秘诀吗?科学家们已经找到了延长蠕虫老鼠,甚至猴子健康寿命的方法。他们的工作揭示了有关衰老生物学的令人兴奋的新线索。但确凿的证据仍然表明,提高长寿和积极生活机会的双11开局火爆淘宝直播4小时涌现130个预售金额超千万元直播间中证网讯(记者杨洁)10月25日,记者自淘宝直播获悉,在10月24日双11预售启动当天20时24时的4个小时里,淘宝直播产生了130个预售金额破千万元的直播间。淘宝直播负责人道放表李宇春金钱也换不来健康娱评大赏近日,李宇春在一档电视节目中,自爆已经患上强直性脊柱炎,最严重的时候每天出行都需要坐轮椅。她在接受采访时说到世界上最贵的品牌汽车躺在我的车库里,但我必须坐在轮椅上,我的房子