2024年最新三,java程序员面试笔试真题库pdf

最后

针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。

image

上述的面试题答案都整理成文档笔记。 也还整理了一些面试资料&最新2021收集的一些大厂的面试真题(都整理成文档,小部分截图)

image

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

总结一下:SecurityContextPersistenceFilter它的作用就是请求来的时候将包含了认证授权信息的SecurityContext对象从SecurityContextRepository中取出交给SecurityContextHolder工具类,方便我们通过SecurityContextHolder获取SecurityContext从而获取到认证授权信息,请求走的时候又把SecurityContextHolder清空,源码如下:

public class SecurityContextPersistenceFilter extends GenericFilterBean {

…省略…

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

…省略部分代码…

HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request,

response);

//从SecurityContextRepository获取到SecurityContext

SecurityContext contextBeforeChainExecution = repo.loadContext(holder);

try {

//把 securityContext设置到SecurityContextHolder,如果没认证通过,这个SecurtyContext就是空的

SecurityContextHolder.setContext(contextBeforeChainExecution);

//调用后面的filter,比如掉用usernamepasswordAuthenticationFilter实现认证

chain.doFilter(holder.getRequest(), holder.getResponse());

}

finally {

//如果认证通过了,这里可以从SecurityContextHolder.getContext();中获取到SecurityContext

SecurityContext contextAfterChainExecution = SecurityContextHolder

.getContext();

// Crucial removal of SecurityContextHolder contents - do this before anything

// else.

//删除SecurityContextHolder中的SecurityContext

SecurityContextHolder.clearContext();

//把SecurityContext 存储到SecurityContextRepository

repo.saveContext(contextAfterChainExecution, holder.getRequest(),

holder.getResponse());

request.removeAttribute(FILTER_APPLIED);

if (debug) {

logger.debug(“SecurityContextHolder now cleared, as request processing completed”);

}

}

…省略…

UsernamePasswordAuthenticationFilter

它的重用是,拦截“/login”登录请求,处理表单提交的登录认证,将请求中的认证信息包括username,password等封装成UsernamePasswordAuthenticationToken,然后调用

AuthenticationManager的认证方法进行认证。

public class UsernamePasswordAuthenticationFilter extends

AbstractAuthenticationProcessingFilter {

// ~ Static fields/initializers

// =====================================================================================

//从登录请求中获取参数:username,password的名字

public static final String SPRING_SECURITY_FORM_USERNAME_KEY = “username”;

public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = “password”;

private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;

private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;

//默认支持POST登录

private boolean postOnly = true;

//默认拦截/login请求,Post方式

public UsernamePasswordAuthenticationFilter() {

super(new AntPathRequestMatcher(“/login”, “POST”));

}

// ~ Methods

// ========================================================================================================

public Authentication attemptAuthentication(HttpServletRequest request,

HttpServletResponse response) throws AuthenticationException {

//判断请求是否是POST

if (postOnly && !request.getMethod().equals(“POST”)) {

throw new AuthenticationServiceException(

"Authentication method not supported: " + request.getMethod());

}

//获取到用户名和密码

String username = obtainUsername(request);

String password = obtainPassword(request);

if (username == null) {

username = “”;

}

if (password == null) {

password = “”;

}

username = username.trim();

//用户名和密码封装Token

UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(

username, password);

//设置details属性

// Allow subclasses to set the “details” property

setDetails(request, authRequest);

//调用AuthenticationManager().authenticate进行认证,参数就是Token对象

return this.getAuthenticationManager().authenticate(authRequest);

}

AuthenticationManager

请求通过UsernamePasswordAuthenticationFilter调用AuthenticationManager,默认走的实现类是ProviderManager,它会找到能支持当前认证的AuthenticationProvider实现类调用器authenticate方法执行认证,认证成功后会清除密码,然后抛出AuthenticationSuccessEvent事件

public class ProviderManager implements AuthenticationManager, MessageSourceAware,

InitializingBean {

…省略…

//这里authentication 是封装了登录请求的认证参数,

//即:UsernamePasswordAuthenticationFilter传入的Token对象

public Authentication authenticate(Authentication authentication)

throws AuthenticationException {

Class<? extends Authentication> toTest = authentication.getClass();

AuthenticationException lastException = null;

AuthenticationException parentException = null;

Authentication result = null;

Authentication parentResult = null;

boolean debug = logger.isDebugEnabled();

//找到所有的AuthenticationProvider ,选择合适的进行认证

for (AuthenticationProvider provider : getProviders()) {

//是否支持当前认证

if (!provider.supports(toTest)) {

continue;

}

if (debug) {

logger.debug("Authentication attempt using "

  • provider.getClass().getName());

}

try {

//调用provider执行认证

result = provider.authenticate(authentication);

if (result != null) {

copyDetails(authentication, result);

break;

}

}

…省略…

}

…省略…

//result就是Authentication ,使用的实现类依然是UsernamepasswordAuthenticationToken,

//封装了认证成功后的用户的认证信息和授权信息

if (result != null) {

if (eraseCredentialsAfterAuthentication

&& (result instanceof CredentialsContainer)) {

// Authentication is complete. Remove credentials and other secret data

// from authentication

//这里在擦除登录密码

((CredentialsContainer) result).eraseCredentials();

}

// If the parent AuthenticationManager was attempted and successful than it will publish an AuthenticationSuccessEvent

// This check prevents a duplicate AuthenticationSuccessEvent if the parent AuthenticationManager already published it

if (parentResult == null) {

//发布事件

eventPublisher.publishAuthenticationSuccess(result);

}

return result;

}

DaoAuthenticationProvider

请求到达AuthenticationProvider,默认实现是DaoAuthenticationProvider,它的作用是根据传入的Token中的username调用UserDetailService加载数据库中的认证授权信息(UserDetails),然后使用PasswordEncoder对比用户登录密码是否正确

public class DaoAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

//密码编码器

private PasswordEncoder passwordEncoder;

//UserDetailsService ,根据用户名加载UserDetails对象,从数据库加载的认证授权信息

private UserDetailsService userDetailsService;

//认证检查方法

protected void additionalAuthenticationChecks(UserDetails userDetails,

UsernamePasswordAuthenticationToken authentication)

throws AuthenticationException {

if (authentication.getCredentials() == null) {

logger.debug(“Authentication failed: no credentials provided”);

throw new BadCredentialsException(messages.getMessage(

“AbstractUserDetailsAuthenticationProvider.badCredentials”,

“Bad credentials”));

}

//获取密码

String presentedPassword = authentication.getCredentials().toString();

//通过passwordEncoder比较密码,presentedPassword是用户传入的密码,userDetails.getPassword()是从数据库加载到的密码

//passwordEncoder编码器不一样比较密码的方式也不一样

if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {

logger.debug(“Authentication failed: password does not match stored value”);

throw new BadCredentialsException(messages.getMessage(

“AbstractUserDetailsAuthenticationProvider.badCredentials”,

“Bad credentials”));

}

}

//检索用户,参数为用户名和Token对象

protected final UserDetails retrieveUser(String username,

UsernamePasswordAuthenticationToken authentication)

throws AuthenticationException {

prepareTimingAttackProtection();

try {

//调用UserDetailsService的loadUserByUsername方法,

//根据用户名检索数据库中的用户,封装成UserDetails

UserDetails loadedUser = this.getUserDetailsService().loadUserByUsername(username);

if (loadedUser == null) {

throw new InternalAuthenticationServiceException(

“UserDetailsService returned null, which is an interface contract violation”);

}

return loadedUser;

}

catch (UsernameNotFoundException ex) {

mitigateAgainstTimingAttack(authentication);

throw ex;

}

catch (InternalAuthenticationServiceException ex) {

throw ex;

}

catch (Exception ex) {

throw new InternalAuthenticationServiceException(ex.getMessage(), ex);

}

}

//创建认证成功的认证对象Authentication,使用的实现是UsernamepasswordAuthenticationToken,

//封装了认证成功后的认证信息和授权信息,以及账户的状态等

@Override

protected Authentication createSuccessAuthentication(Object principal,

Authentication authentication, UserDetails user) {

boolean upgradeEncoding = this.userDetailsPasswordService != null

&& this.passwordEncoder.upgradeEncoding(user.getPassword());

if (upgradeEncoding) {

String presentedPassword = authentication.getCredentials().toString();

String newPassword = this.passwordEncoder.encode(presentedPassword);

user = this.userDetailsPasswordService.updatePassword(user, newPassword);

}

return super.createSuccessAuthentication(principal, authentication, user);

}

…省略…

这里提供了三个方法

  • additionalAuthenticationChecks:通过passwordEncoder比对密码

  • retrieveUser:根据用户名调用UserDetailsService加载用户认证授权信息

  • createSuccessAuthentication:登录成功,创建认证对象Authentication

分享

首先分享一份学习大纲,内容较多,涵盖了互联网行业所有的流行以及核心技术,以截图形式分享:

(亿级流量性能调优实战+一线大厂分布式实战+架构师筑基必备技能+设计思想开源框架解读+性能直线提升架构技术+高效存储让项目性能起飞+分布式扩展到微服务架构…实在是太多了)

其次分享一些技术知识,以截图形式分享一部分:

Tomcat架构解析:

算法训练+高分宝典:

Spring Cloud+Docker微服务实战:

最后分享一波面试资料:

切莫死记硬背,小心面试官直接让你出门右拐

1000道互联网Java面试题:

Java高级架构面试知识整理:

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

(img-UImRslGf-1715235561458)]

算法训练+高分宝典:

[外链图片转存中…(img-t58dTLXE-1715235561458)]

Spring Cloud+Docker微服务实战:

[外链图片转存中…(img-cQjNK9iU-1715235561459)]

最后分享一波面试资料:

切莫死记硬背,小心面试官直接让你出门右拐

1000道互联网Java面试题:

[外链图片转存中…(img-3tDvSleq-1715235561459)]

Java高级架构面试知识整理:

[外链图片转存中…(img-h4nIuCiR-1715235561459)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值