import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
/**
- 资源服务配置
*/
@Configuration
@EnableResourceServer
public class AuthResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated();
}
}
JwtTokenStoreConfig
package com.b8.auth.config;
import com.b8.auth.enhancer.B8AuthTokenEnhancer;
import com.b8.auth.properties.JwtCAProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.rsa.crypto.KeyStoreKeyFactory;
import java.security.KeyPair;
@Configuration
@EnableConfigurationProperties(value = JwtCAProperties.class)
public class JwtTokenStoreConfig {
@Bean
public TokenStore jwtTokenStore(){
return new JwtTokenStore(jwtAccessTokenConverter());
}
@Bean
public B8AuthTokenEnhancer b8AuthTokenEnhancer() {
return new B8AuthTokenEnhancer();
}
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter(){
JwtAccessTokenConverter accessTokenConverter = new
JwtAccessTokenConverter();
//配置JWT使用的秘钥 非对称加密
accessTokenConverter.setKeyPair(keyPair());
return accessTokenConverter;
}
@Autowired
private JwtCAProperties jwtCAProperties;
@Bean
public KeyPair keyPair() {
KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource(jwtCAProperties.getKeyPairName()), jwtCAProperties.getKeyPairSecret().toCharArray());
return keyStoreKeyFactory.getKeyPair(jwtCAProperties.getKeyPairAlias(), jwtCAProperties.getKeyPairStoreSecret().toCharArray());
}
}
RedisConfig
package com.b8.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.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
/**
- @author zhiwei Liao
*/
@Configuration
public class RedisConfig {
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Bean
public TokenStore tokenStore(){
// access_token
return new RedisTokenStore(redisConnectionFactory);
}
}
WebSecurityConfig
package com.b8.auth.config;
import com.b8.auth.service.B8AuthUserDetailService;
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.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
-
@Description 配置SpringSecurity,“将Spring Security与Spring Gateway一起使用时出现无法访问javax.servlet.Filter”错误”,
-
把Spring Gateway和Spring Security放在一起,因为我想保护我的网关。但是在实现了以下扩展WebSecurityConfigurerAdapter的类之后,
-
项目抛出java:无法访问javax.servlet.Filter
-
从Spring Cloud Gateway文档中:Spring Cloud Gateway需要Spring Boot和Spring Webflux提供的Netty运行时。
-
它不能在传统的Servlet容器中工作,也不能在构建为WAR时工作。扩展WebSecurityConfigurerAdapter是为了基于servlet的应用程序
-
@Author zhiwei Liao
-
@Date 2021/8/17 15:44
**/
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private B8AuthUserDetailService userDetailService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailService);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
/**
-
@Description 密码模式
-
@MethodReturnType org.springframework.security.crypto.password.PasswordEncoder
-
@Author zhiwei Liao
-
@Date 2021/8/17 15:46
**/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().permitAll()
.and().authorizeRequests()
.antMatchers(“/oauth/**”).permitAll()//不拦截
.anyRequest()
.authenticated()
.and().logout().permitAll()//退出放行
.and().csrf().disable();
}
}
UserinfoDetails
package com.b8.auth.domain;
import com.common.entity.po.B8UserUserinfoEntity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Arrays;
import java.util.Collection;
/**
- @author zhiwei Liao
*/
public class UserinfoDetails implements UserDetails {
private B8UserUserinfoEntity userUserinfo;
public UserinfoDetails(B8UserUserinfoEntity userUserinfo) {
this.userUserinfo = userUserinfo;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
//返回当前用户的权限 BRAC user role authority
return Arrays.asList(new SimpleGrantedAuthority(“TEST”));
}
// 获取用户密码(凭证)
@Override
public String getPassword() {
return userUserinfo.getCredential();
}
// 获取用户名
@Override
public String getUsername() {
return userUserinfo.getNickNameId();
}
// 判断帐号是否已经过期
@Override
public boolean isAccountNonExpired() {
return true;
}
// 判断帐号是否已被锁定
@Override
public boolean isAccountNonLocked() {
return true;
}
// 判断用户凭证是否已经过期
@Override
public boolean isCredentialsNonExpired() {
return true;
}
// 判断用户帐号是否已启用
@Override
public boolean isEnabled() {
return !userUserinfo.getUserStatus().equals(“FREEZE”);
}
public B8UserUserinfoEntity getUserUserinfo() {
return userUserinfo;
}
}
B8AuthTokenEnhancer
package com.b8.auth.enhancer;
import com.b8.auth.domain.UserinfoDetails;
import com.common.entity.po.B8UserUserinfoEntity;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import java.util.HashMap;
import java.util.Map;
public class B8AuthTokenEnhancer implements TokenEnhancer {
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
UserinfoDetails userinfoDetails = (UserinfoDetails) authentication.getPrincipal();
final Map<String, Object> additionalInfo = new HashMap<>();
final Map<String, Object> retMap = new HashMap<>();
//todo 这里暴露userId到Jwt的令牌中,后期可以根据自己的业务需要 进行添加字段
additionalInfo.put(“userId”,userinfoDetails.getUserUserinfo().getId());
additionalInfo.put(“userName”,userinfoDetails.getUserUserinfo().getNickNameId());
additionalInfo.put(“nickName”,userinfoDetails.getUserUserinfo().getDisplayName());
additionalInfo.put(“loginType”,userinfoDetails.getUserUserinfo().getLoginType());
retMap.put(“additionalInfo”,additionalInfo);
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(retMap);
return accessToken;
}
}
JwtCAProperties
package com.b8.auth.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
-
@Description 读取配置文件中的属性配置
-
@Author zhiwei Liao
-
@Date 2021/8/18 10:04
**/
@Data
@ConfigurationProperties(prefix = “b8auth.jwt”)
public class JwtCAProperties {
/**
- 证书名称
*/
private String keyPairName;
/**
- 证书别名
*/
private String keyPairAlias;
/**
- 证书私钥
*/
private String keyPairSecret;
/**
- 证书存储密钥
*/
private String keyPairStoreSecret;
}
UserServiceHystrix
package com.b8.auth.service.impl;
import com.b8.auth.api.ResultData;
import com.b8.auth.service.UserInfoFeignService;
import com.common.entity.po.B8UserUserinfoEntity;
import org.springframework.stereotype.Component;
/**
-
@author zhiwei Liao
-
@version 1.0
-
@Description
-
@Date 2021/8/17 15:25
*/
@Component
public class UserServiceHystrix implements UserInfoFeignService {
@Override
public ResultData getUserinfoById(String userId) {
return null;
}
@Override
public ResultData getUserByUsername(String username) {
return null;
}
}
B8AuthUserDetailService
package com.b8.auth.service;
import com.b8.auth.api.ResultData;
import com.b8.auth.domain.UserinfoDetails;
import com.common.entity.po.B8UserUserinfoEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
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;
/**
-
@author zhiwei Liao
-
@version 1.0
-
@Description
-
@Date 2021/8/17 15:02
*/
@Service
@Slf4j
public class B8AuthUserDetailService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// TODO 查数据库获取用户信息 rpc调用
// 加载用户信息
if (StringUtils.isEmpty(username)) {
log.warn(“用户登陆用户名为空:{}”, username);
throw new UsernameNotFoundException(“用户名不能为空”);
}
B8UserUserinfoEntity userUserinfo = getByUsername(username);
if (null == userUserinfo) {
log.warn(“根据用户名没有查询到对应的用户信息:{}”, username);
}
log.info(“根据用户名:{}获取用户登陆信息:{}”, username, userUserinfo);
// 用户信息的封装 implements UserDetails
UserinfoDetails memberDetails = new UserinfoDetails(userUserinfo);
return memberDetails;
}
@Autowired
private UserInfoFeignService userInfoFeignService;
public B8UserUserinfoEntity getByUsername(String username) {
// fegin获取用户信息
ResultData resultData = userInfoFeignService.getUserByUsername(username);
return resultData.getData();
}
}
UserInfoFeignService
package com.b8.auth.service;
import com.b8.auth.api.ResultData;
import com.b8.auth.service.impl.UserServiceHystrix;
import com.common.entity.po.B8UserUserinfoEntity;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
-
@author zhiwei Liao
-
@version 1.0
-
@Description
-
@Date 2021/8/17 15:24
*/
@Component
@FeignClient(name = “user”, fallback = UserServiceHystrix.class, path = “/user”)
public interface UserInfoFeignService {
@GetMapping(“/getUserinfoById”)
ResultData getUserinfoById(@RequestParam(“userId”) String userId);
@GetMapping(“/getUserByUsername”)
ResultData getUserByUsername(@RequestParam(“username”) String username);
}
IErrorCode
package com.b8.auth.api;
/**
- 封装API的错误码
*/
public interface IErrorCode {
int getCode();
String getMessage();
}
ResultCode
package com.b8.auth.api;
/**
- 枚举了一些常用API操作码
*/
public enum ResultCode implements IErrorCode {
SUCCESS(200, “操作成功”),
FAILED(500, “操作失败”),
VALIDATE_FAILED(404, “参数检验失败”),
UNAUTHORIZED(401, “暂未登录或token已经过期”),
AUTHORIZATION_HEADER_IS_EMPTY(600,“请求头中的token为空”),
GET_TOKEN_KEY_ERROR(601,“远程获取TokenKey异常”),
GEN_PUBLIC_KEY_ERROR(602,“生成公钥异常”),
JWT_TOKEN_EXPIRE(603,“token校验异常”),
TOMANY_REQUEST_ERROR(429,“后端服务触发流控”),
BACKGROUD_DEGRADE_ERROR(604,“后端服务触发降级”),
BAD_GATEWAY(502,“网关服务异常”),
FORBIDDEN(403, “没有相关权限”);
private int code;
private String message;
private ResultCode(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}
ResultData
package com.b8.auth.api;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@NoArgsConstructor
public class ResultData implements Serializable {
/**
- 状态码
*/
public boolean status = true;
/**
- 状态码
*/
private Integer code = 200;
/**
- 接口返回信息
*/
private String msg;
/**
- 数据对象
*/
private T data;
/**
-
初始化一个新创建的 ResultData 对象
-
@param status 状态码
-
@param msg 返回内容
*/
public ResultData(Boolean status, String msg) {
this.status = status;
this.msg = msg;
}
/**
-
初始化一个新创建的 ResultData 对象
-
@param status 状态码
-
@param msg 返回内容
-
@param data 数据对象
*/
public ResultData(Boolean status, String msg, T data, Integer code) {
this.status = status;
this.msg = msg;
this.data = data;
this.code = code;
}
public ResultData(T data) {
this.data = data;
}
/**
-
返回成功消息
-
@param msg 返回内容
-
@param data 数据对象
-
@return 成功消息
*/
public static ResultData success(String msg, T data) {
return new ResultData(true, msg, data, 200);
}
/**
-
返回成功消息
-
@param msg 返回内容
-
@return 成功消息
*/
public static ResultData success(String msg) {
return ResultData.success(msg, null);
}
/**
-
返回成功消息
-
@return 成功消息
*/
public static ResultData success() {
return ResultData.success(null);
}
/**
-
返回成功数据
-
@return 成功消息
*/
public static ResultData success(T data) {
return ResultData.success(null, data);
}
/**
-
返回错误消息
-
@return
*/
public static ResultData error() {
return ResultData.error(null);
}
/**
-
返回错误消息
-
@param msg 返回内容
-
@return 警告消息
*/
public static ResultData error(String msg) {
return ResultData.error(msg, null);
}
/**
-
返回错误消息
-
@param code 状态码
-
@param msg 返回内容
-
@return 警告消息
*/
public static ResultData error(Integer code, String msg) {
return new ResultData(false, msg, null, code);
}
/**
-
返回错误消息
-
@param msg 返回内容
-
@param data 数据对象
-
@return 警告消息
*/
public static ResultData error(String msg, T data) {
return new ResultData(false, msg, data, 500);
}
}
B8AuthApplication
package com.b8.auth;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/224f171cb92ce4dc2402d8b43afca493.jpeg)
最后
关于面试刷题也是有方法可言的,建议最好是按照专题来进行,然后由基础到高级,由浅入深来,效果会更好。当然,这些内容我也全部整理在一份pdf文档内,分成了以下几大专题:
- Java基础部分
- 算法与编程
- 数据库部分
- 流行的框架与新技术(Spring+SpringCloud+SpringCloudAlibaba)
这份面试文档当然不止这些内容,实际上像JVM、设计模式、ZK、MQ、数据结构等其他部分的面试内容均有涉及,因为文章篇幅,就不全部在这里阐述了。
作为一名程序员,阶段性的学习是必不可少的,而且需要保持一定的持续性,这次在这个阶段内,我对一些重点的知识点进行了系统的复习,一方面巩固了自己的基础,另一方面也提升了自己的知识广度和深度。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
@SpringBootApplication
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-yQbnsuZ3-1713319524952)]
[外链图片转存中…(img-UXByvCYg-1713319524952)]
[外链图片转存中…(img-PsQLbVDU-1713319524953)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/224f171cb92ce4dc2402d8b43afca493.jpeg)
最后
关于面试刷题也是有方法可言的,建议最好是按照专题来进行,然后由基础到高级,由浅入深来,效果会更好。当然,这些内容我也全部整理在一份pdf文档内,分成了以下几大专题:
- Java基础部分
[外链图片转存中…(img-VjEs3krI-1713319524953)]
- 算法与编程
[外链图片转存中…(img-nmOhiJFz-1713319524953)]
- 数据库部分
[外链图片转存中…(img-6UOPllSX-1713319524953)]
- 流行的框架与新技术(Spring+SpringCloud+SpringCloudAlibaba)
[外链图片转存中…(img-u7YmksMX-1713319524954)]
这份面试文档当然不止这些内容,实际上像JVM、设计模式、ZK、MQ、数据结构等其他部分的面试内容均有涉及,因为文章篇幅,就不全部在这里阐述了。
作为一名程序员,阶段性的学习是必不可少的,而且需要保持一定的持续性,这次在这个阶段内,我对一些重点的知识点进行了系统的复习,一方面巩固了自己的基础,另一方面也提升了自己的知识广度和深度。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!