0


Oauth2使用postman登录获取token

Oauth2使用postman登录获取token

  1. 网关请求拦截-(CheckJwtFilter.java)packagecom.xiaoge.config;importcom.fasterxml.jackson.core.JsonProcessingException;importcom.fasterxml.jackson.databind.ObjectMapper;importcom.xiaoge.constant.GatewayConstant;importorg.apache.commons.lang.StringUtils;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.cloud.gateway.filter.GatewayFilter;importorg.springframework.cloud.gateway.filter.GatewayFilterChain;importorg.springframework.cloud.gateway.filter.GlobalFilter;importorg.springframework.context.annotation.Configuration;importorg.springframework.core.Ordered;importorg.springframework.core.io.buffer.DataBuffer;importorg.springframework.core.io.buffer.DataBufferFactory;importorg.springframework.data.redis.core.StringRedisTemplate;importorg.springframework.http.HttpHeaders;importorg.springframework.http.HttpStatus;importorg.springframework.http.server.reactive.ServerHttpRequest;importorg.springframework.http.server.reactive.ServerHttpResponse;importorg.springframework.util.CollectionUtils;importorg.springframework.web.server.ServerWebExchange;importreactor.core.publisher.Mono;importjava.util.HashMap;importjava.util.List;importjava.util.Map;/** * @Classname CheckJwtFilter * @Date 2022/3/20 下午4:49 * @Created by xiaoge * @Description TODO */@ConfigurationpublicclassCheckJwtFilterimplementsGlobalFilter,Ordered{@AutowiredprivateStringRedisTemplate redisTemplate;/** * 过滤请求, 判断是否有jwt, 有放行, 没拦截 * @param exchange * @param chain * @return */@OverridepublicMono<Void>filter(ServerWebExchange exchange,GatewayFilterChain chain){ServerHttpRequest request = exchange.getRequest();// 获取路径String path = request.getURI().getPath();// 判断该路径是否在放行路径中if(GatewayConstant.ALLOW_PATH.contains(path)){return chain.filter(exchange);}// 判断该请求头中是否包含AuthorizationHttpHeaders headers = request.getHeaders();List<String> list = headers.get(GatewayConstant.AUTHORIZATION);if(!CollectionUtils.isEmpty(list)){String token = list.get(0);if(StringUtils.isNotBlank(token)){String jwt = token.replace("bearer ","");if(StringUtils.isNotBlank(jwt)){// 看redis是否还有该tokenBoolean hasKey = redisTemplate.hasKey(GatewayConstant.OAUTH_PREFIX + jwt);if(hasKey){return chain.filter(exchange);}}}}// 这里就是没有 jwt 了,返回 401ServerHttpResponse response = exchange.getResponse();// 设置响应头 response.getHeaders().add("content-type","application/json;charset=utf-8");Map<String,Object> map =newHashMap<>(); map.put("code",HttpStatus.UNAUTHORIZED.value()); map.put("msg","非法访问!");ObjectMapper objectMapper =newObjectMapper();byte[] bytes =null;try{ bytes = objectMapper.writeValueAsBytes(map);}catch(JsonProcessingException e){ e.printStackTrace();}DataBuffer buffer = response.bufferFactory().wrap(bytes);return response.writeWith(Mono.just(buffer));}/** * 执行顺序 越小越先 要比-1 小 * @return */@OverridepublicintgetOrder(){return-2;}}
  2. 网关配置把获取到的token存入redis-(GatewayConfig.java)它是把我们访问网关的路由转发到授权微服务packagecom.xiaoge.config;importcn.hutool.json.JSONObject;importcn.hutool.json.JSONUtil;importcom.xiaoge.constant.GatewayConstant;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.cloud.gateway.route.RouteLocator;importorg.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.data.redis.core.StringRedisTemplate;importreactor.core.publisher.Mono;importjava.time.Duration;importjava.util.concurrent.TimeUnit;/** * @Classname GatewayConfig * @Date 2022/3/20 下午5:18 * @Created by xiaoge * @Description TODO */@ConfigurationpublicclassGatewayConfig{@AutowiredprivateStringRedisTemplate redisTemplate;/** * 描述: 给授权专门做的存入 token 路由 * * @param builder: * @return org.springframework.cloud.gateway.route.RouteLocator */@BeanpublicRouteLocatorrouteLocator(RouteLocatorBuilder builder){return builder .routes().route("auth-server-router", r -> r.path("/oauth/**").filters(f -> f.modifyResponseBody(String.class,String.class,(exchanges, s)->{String path = exchanges.getRequest().getURI().getPath();if("/oauth/token".equals(path)){//如果是登录的请求,那么得到的 s 就是 token 的一套JSONObject jsonObject =JSONUtil.parseObj(s);// 判断jsonObject 是否包含access_tokenif(jsonObject.containsKey("access_token")){//如果包含 access_token 就放进 redis 里面// token值String access_token = jsonObject.getStr("access_token");// 过期时间Long expires_in = jsonObject.getLong("expires_in");// 存入redis中 redisTemplate.opsForValue().set(GatewayConstant.OAUTH_PREFIX + access_token,"",Duration.ofSeconds(expires_in));}}returnMono.just(s);})).uri("lb://auth-server")).build();}}
  3. 授权服务认证配置-(AuthorizationConfig.java)packagecom.xiaoge.config;importcom.xiaoge.service.impl.UserDetailsServiceImpl;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.core.io.ClassPathResource;importorg.springframework.security.authentication.AuthenticationManager;importorg.springframework.security.crypto.password.PasswordEncoder;importorg.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;importorg.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;importorg.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;importorg.springframework.security.oauth2.provider.token.TokenStore;importorg.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;importorg.springframework.security.oauth2.provider.token.store.JwtTokenStore;importorg.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;importjava.security.KeyPair;/** * @Author: ZhangXiao * @DateTime: 2022/4/7 15:59 * @Description: * 1. token的存储 * 2. jwt的转换器 * 3. 第三方应用 * 4. endpoints暴露 */@ConfigurationpublicclassAuthorizationConfigextendsAuthorizationServerConfigurerAdapter{@AutowiredprivatePasswordEncoder passwordEncoder;@AutowiredprivateAuthenticationManager authenticationManager;@AutowiredprivateUserDetailsServiceImpl userDetailsService;/** * 使用 jwt 存放 token * @return */@BeanpublicTokenStoretokenStore(){returnnewJwtTokenStore(jwtAccessTokenConverter());}/** * 使用非对称加密的方式 * @return */@BeanpublicJwtAccessTokenConverterjwtAccessTokenConverter(){JwtAccessTokenConverter jwtAccessTokenConverter =newJwtAccessTokenConverter();// 把私钥读到内存中ClassPathResource resource =newClassPathResource("cxs-jwt.jks");// 创建一个钥匙工厂KeyStoreKeyFactory keyStoreKeyFactory =newKeyStoreKeyFactory(resource,"cxs123".toCharArray());// 获取钥匙, 传入钥匙别名KeyPair privateKey = keyStoreKeyFactory.getKeyPair("cxs-jwt");// 设置进转换器里面 jwtAccessTokenConverter.setKeyPair(privateKey);return jwtAccessTokenConverter;}/** * 配置第三方应用 * password 只要是登录都用这个授权方式 * 客户端授权 用于微服务之间自发的进行远程调用时 资源服务器必须要token的情况, 当然也是可以放行服务提供者的接口的 * * * 描述: 一个 web 平台,用于第三方访问 * 一个 sxt 平台,内部访问的,例如 mq 里发起远程调用 * @param clients * @throws Exception */@Overridepublicvoidconfigure(ClientDetailsServiceConfigurer clients)throwsException{ clients.inMemory()// 配置第三方引用.withClient("web")// 浏览器.secret(passwordEncoder.encode("web-secret"))// 密码加密方式.scopes("all")// 作用域.authorizedGrantTypes("password")// 授权类型 密码授权.accessTokenValiditySeconds(7200)// token的时间7200秒.redirectUris("https://www.baidu.com")// token过期从定向地址.and()// 上面是密码授权方式, 下面是客户端授权.withClient("client")// 微服务之间自发的调用.secret(passwordEncoder.encode("client-secret"))// 密码加密方式.scopes("read")// 只读 业务方面的一个配置.authorizedGrantTypes("client_credentials")// 授权类型 客户端授权.accessTokenValiditySeconds(Integer.MAX_VALUE)// token过期时间 66年.redirectUris("https://www.baidu.com");// token过期从定向地址}/** * 暴露出去 * @param endpoints * @throws Exception */@Overridepublicvoidconfigure(AuthorizationServerEndpointsConfigurer endpoints)throwsException{ endpoints .userDetailsService(userDetailsService)// 暴露密码登录实现类.authenticationManager(authenticationManager)// 暴露密码登录需要的认证管理器.tokenStore(tokenStore())// 暴露tokenStore.accessTokenConverter(jwtAccessTokenConverter());// 暴露jwt转换器super.configure(endpoints);}}
  4. 授权服务安全配置-(WebSecurityConfig.java)packagecom.xiaoge.config;importcom.xiaoge.service.impl.UserDetailsServiceImpl;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.security.authentication.AuthenticationManager;importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;/** * @Author: ZhangXiao * @DateTime: 2022/4/7 15:56 * @Description: */@ConfigurationpublicclassWebSecurityConfigextendsWebSecurityConfigurerAdapter{@AutowiredprivateUserDetailsServiceImpl userDetailsService;/** * 认证管理器 密码登录需要认证管理器 * @return * @throws Exception */@BeanpublicAuthenticationManagerauthenticationManager()throwsException{returnsuper.authenticationManager();}/** * 走自己的登录 密码登录需要的 * @param auth * @throws Exception */@Overrideprotectedvoidconfigure(AuthenticationManagerBuilder auth)throwsException{//走自己的登录 auth.userDetailsService(userDetailsService);}}
  5. 授权服务登录-(UserDetailsServiceImpl.java)packagecom.xiaoge.service.impl;importcom.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;importcom.xiaoge.constant.AuthConstant;importcom.xiaoge.domain.SysUser;importcom.xiaoge.mapper.SysUserMapper;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.security.core.userdetails.UserDetails;importorg.springframework.security.core.userdetails.UserDetailsService;importorg.springframework.security.core.userdetails.UsernameNotFoundException;importorg.springframework.stereotype.Service;importorg.springframework.util.CollectionUtils;importorg.springframework.util.ObjectUtils;importorg.springframework.util.StringUtils;importorg.springframework.web.context.request.RequestContextHolder;importorg.springframework.web.context.request.ServletRequestAttributes;importjavax.servlet.http.HttpServletRequest;importjava.util.List;/** * @Author: ZhangXiao * @DateTime: 2022/4/7 16:10 * @Description: */@ServicepublicclassUserDetailsServiceImplimplementsUserDetailsService{@AutowiredprivateSysUserMapper sysUserMapper;/** * 登录方法 * @param username * @return * @throws UsernameNotFoundException */@OverridepublicUserDetailsloadUserByUsername(String username)throwsUsernameNotFoundException{// 获取requestServletRequestAttributes requestAttributes =(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();HttpServletRequest request = requestAttributes.getRequest();// 获取请求头信息String loginType = request.getHeader(AuthConstant.LOGIN_TYPE);if(StringUtils.isEmpty(loginType)){returnnull;}// 选择switch(loginType){caseAuthConstant.SYS_USER:// 后台用户 就查后台的sys_user表SysUser sysUser = sysUserMapper.selectOne(newLambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username ));if(!ObjectUtils.isEmpty(sysUser)){// 查询权限List<String> auths = sysUserMapper.findUserAuthsById(sysUser.getUserId());if(!CollectionUtils.isEmpty(auths)){// 设置权限 sysUser.setAuths(auths);}}return sysUser;caseAuthConstant.MEMBER:// 前台用户returnnull;default:returnnull;}}}
  6. 授权服务启动类-(AuthServerApplication.class) (一定要加这个认证注解EnableAuthorizationServer, 因为WebSecurityConfig配置了认证管理器)packagecom.xiaoge;importorg.mybatis.spring.annotation.MapperScan;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.cloud.netflix.eureka.EnableEurekaClient;importorg.springframework.context.annotation.Bean;importorg.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;importorg.springframework.security.crypto.password.PasswordEncoder;importorg.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;/** * @Author: ZhangXiao * @DateTime: 2022/4/7 15:36 * @Description: */@SpringBootApplication@EnableAuthorizationServer// 开启授权服务器@EnableEurekaClient// 开启eureka客户端@MapperScan(basePackages ="com.xiaoge.mapper")publicclassAuthServerApplication{publicstaticvoidmain(String[] args){SpringApplication.run(AuthServerApplication.class, args);}/** * 密码加密器 * @return */@BeanpublicPasswordEncoderpasswordEncoder(){returnnewBCryptPasswordEncoder();}}
  7. postman-Authorization(web web-secret grant_type(认证方式)是AuthorizationConfig类中配置的)在这里插入图片描述在这里插入图片描述 源码地址:https://gitee.com/xiaogectwbq/ego-shop-cloud
标签: postman java restful

本文转载自: https://blog.csdn.net/zsx1314lovezyf/article/details/124616097
版权归原作者 只因为你而温柔 所有, 如有侵权,请联系我们删除。

“Oauth2使用postman登录获取token”的评论:

还没有评论