最后
这份《“java高分面试指南”-25分类227页1000+题50w+字解析》同样可分享给有需要的朋友,感兴趣的伙伴们可挑战一下自我,在不看答案解析的情况,测试测试自己的解题水平,这样也能达到事半功倍的效果!(好东西要大家一起看才香)
}
自己创建实现类
import com.young.security.mysecurity.pojo.Role;
import com.young.security.mysecurity.pojo.User;
import com.young.security.mysecurity.repository.RoleRepository;
import com.young.security.mysecurity.repository.UserRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
-
Create by stefan
-
Date on 2018-05-17 22:49
-
Convertion over Configuration!
*/
@Component
@Slf4j
public class MyUserDetailService implements UserDetailsService {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
UserRepository userRepository;
@Autowired
private RoleRepository roleRepository;
@Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
User user = userRepository.findByUsername(name);
if (user==null){
throw new AuthenticationCredentialsNotFoundException(“authError”);
}
log.info(“{}”,user);
List role = roleRepository.findByUsername(name);
log.info(“{}”,role);
List authorities = new ArrayList<>();
role.forEach(role1 -> authorities.addAll(AuthorityUtils.commaSeparatedStringToAuthorityList(“ROLE_”+role1.getRolename())));
log.info(“{}”,authorities);
return new org.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),authorities);
}
}
任何关于数据库的业务这里不做解释。详情请看源码。
需要注意的是 Security默认使用了密码加密保护,我们配置密码转换器申明使用什么加密方式。这里推荐BCryptPassword,同样是5.0的推荐。
在刚才配置类SecurityConfig中配置
@Bean
public static PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
查看源码encode()这个方法是加密,matches()是判断加密密码与输入框明文密码是否一致。
拦截请求
接下来,我们看看
@Override
protected void configure(HttpSecurity http){
super.configure(http);
}
默认配置是
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.httpBasic();
}
自己修改后的配置
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().loginPage(“/signIn”).loginProcessingUrl(“/user/userLogin”)
.and()
.logout().logoutUrl(“/logout”)
.and()
.authorizeRequests()
.antMatchers(“/signIn”,“/hello”).permitAll()
.antMatchers(“/index”).authenticated()
.antMatchers(“/admin/**”,“/add”).hasRole(“ADMIN”)
.regexMatchers(“/admin1/.*”).access(“hasRole(‘ADMIN’) or hasRole(‘ADMIN1’)”)
.anyRequest().authenticated()
.and()
.requiresChannel().antMatchers(“/add”).requiresSecure()//https://127.0.0.1:8443/add
.and()
.rememberMe().tokenValiditySeconds(2419200).tokenRepository(persistentTokenRepository());
}
spring security 的拦截语法
我们首先调用authorizeRequests(),然后调用该方法所返回的对象的方法来配置请求级别的安全性细节。
antMatchers的使用(Ant风格的通配符):
指定一个路径
antMatchers(“/index”)
指定多个路径
antMatchers(“/admin/**”,“/add”)
指定请求方式
antMatchers(HttpMethod.POST,“/add”)
与之相似的还有一个regexMatchers,接收正则表达式来定义请求路径。
regexMatchers(“/admin1/.*”)
路径选择好之后我们就要保护路径了。如下表:
注意:这些规则是按配置的先后顺序发挥作用的,所以将具体的请求路径放在前面,而越来越不具体的放在后面,如果不这样的话,不具体的路径配置会覆盖掉更为具体的路径配置。
使用spring 表达式进行安全保护
hasRole()一次仅仅只能限制角色,倘若我们还要同时限制ip地址的权限不好配置了。
这里我们可以使用SpEL 作为声明访问限制的一种,具体使用如下
.regexMatchers(“/admin1/.*”).access(“hasRole(‘ADMIN’) or hasRole(‘ADMIN1’)”)
显然access()这种方式更为强大。
强制通道的安全性
现在大部分网路传输都用HTTPS,
将请求变为HTTPS很简单
.requiresChannel().antMatchers(“/add”).requiresSecure()//https://127.0.0.1:8443/add
当请求http://127.0.0.1:8080/add,security会自动跳转到https://127.0.0.1:8443/add进行加密请求。
防止跨站请求伪造
从Security3.2开始,默认就会启用CSPF防护。可以关闭,也可以在表单中做一些改动。
.csrf().disable() 禁用CSRF防护功能。
为了安全,本人建议启用CSRF防护,在表单中做改动。也很简单在表单中加一个
在freemarker页面form表单中添加
更具体关于CSRF的知识请自行查找资料。
认证用户
添加自定义的登录页
security默认是提供了一个登陆页面,但是并不能满足我们的要求。我们可以自定义登陆页。
.formLogin().loginPage(“/signIn”).loginProcessingUrl(“/user/userLogin”)
对应视图页面:
username:
password:
/user/userLogin这个路由的controller我们无需定义。
启用Remember-me 功能
示例:
//存在cookie,并限定过期时间
.rememberMe().tokenValiditySeconds(2419200)
记住功能,我们可以把用户信息存在cookie,也可以存在数据库。
要想存在数据库,如下配置,
.rememberMe().tokenValiditySeconds(2419200).tokenRepository(persistentTokenRepository());
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
tokenRepository.setDataSource(dataSource);
//tokenRepository.setCreateTableOnStartup(true);
return tokenRepository;
}
第一次运行
tokenRepository.setCreateTableOnStartup(true);会在数据库自动建立一张表,再次运行时请注释掉,否则会报错。
要想启动Remember-me功能还需要在登录表单中改动
记住我
name=”remember-me”是固定的。
当然也可以不需要改动前端页面,可以在配置类直接开启记住功能(.alwaysRemember(true)),强制让用户记住。
.rememberMe().tokenValiditySeconds(2419200).tokenRepository(persistentTokenRepository()).alwaysRemember(true);
退出
.logout().logoutSuccessUrl(“/signIn”)
开启csrf防护的logout默认是post请求。
保护视图
为了测试视图保护标签,不得不换了Thymeleaf ,毕竟人家是官方认可的,freemarker虽然好用但是毕竟是屌丝出身,虽说能用jsp的标签库,但是搜集了很多资料依然没弄明白怎么配置,只好用Thymeleaf。
使用Thymeleaf的Spring Security方言
书上还给了一个配置bean 声明SringTemplateEnginebean。但是我试验了,不用配置也可以。
只需两步:
结局:总结+分享
看完美团、字节、腾讯这三家的一二三面试问题,是不是感觉问的特别多,可能咱们真的又得开启面试造火箭、工作拧螺丝的模式去准备下一次的面试了。
开篇有提及我可是足足背下了Java互联网工程师面试1000题,多少还是有点用的呢,换汤不换药,不管面试官怎么问你,抓住本质即可!能读到此处的都是真爱
- Java互联网工程师面试1000题
而且从上面三家来看,算法与数据结构是必备不可少的呀,因此我建议大家可以去刷刷这本左程云大佬著作的 《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题。
- 程序员代码面试指南–IT名企算法与数据结构题目最优解
- 其余像设计模式,建议可以看看下面这4份PDF(已经整理)
- 更多的Java面试学习笔记如下,关于面试这一块,我额外细分出Java基础-中级-高级开发的面试+解析,以及调优笔记等等等。。。
以上所提及的全部Java面试学习的PDF及笔记,如若皆是你所需要的,那么都可发送给你!
因此我建议大家可以去刷刷这本左程云大佬著作的 《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题。
- 程序员代码面试指南–IT名企算法与数据结构题目最优解
[外链图片转存中…(img-QGUuFUkP-1715120593311)]
- 其余像设计模式,建议可以看看下面这4份PDF(已经整理)
[外链图片转存中…(img-dof5heB4-1715120593311)]
- 更多的Java面试学习笔记如下,关于面试这一块,我额外细分出Java基础-中级-高级开发的面试+解析,以及调优笔记等等等。。。
[外链图片转存中…(img-SJKPlIy3-1715120593312)]
以上所提及的全部Java面试学习的PDF及笔记,如若皆是你所需要的,那么都可发送给你!