Spring Security 导致Druid登录失败分析

开发的时候遇到的问题Spring Security 默认情况下会拦截所有的页面,包括Druid默认的/druid/ 页面,在校验身份放行后来到Druid登录页面输入账号密码仍无法正常登录…

排查问题

通过http请求的分析

提交请求403

排查了一下发现是由于Spring Security 的CSRF导致的

解决方案

方案一:直接关闭Spring Security 的CSRF功能

在Spring Security 的配置中将csrf 禁用

配置类
1
2
3
4
http.authorizeRequests().antMatchers("/").permitAll()
.antMatchers("/druid/**").hasRole("admin")
.and().csrf().disable()
.formLogin().and().logout();

缺点:全局关闭不合适,系统不安全

方案二:忽略Druid入口的CSRF(推荐)

配置类
1
2
3
4
5
6
http.authorizeRequests().antMatchers("/").permitAll()
.antMatchers("/druid/**").hasRole("admin")
.and().formLogin().and().logout();

// 忽略druid 的 csrf
http.csrf().ignoringAntMatchers("/druid/**");

Spring Boot 注册 Servlet 三大组件

摘要
三大组件包括 Servlet、Filter、Listener
由于SpringBoot默认是以jar包的方式启动嵌入式的Servlet容器来启动SpringBoot的web应用,所以没有web.xml文件。

三大组件的注册

这个注册都是在自定义的配置类里面注册(即有@Configraution的类里)

ServletRegistrationBean

P.s. 这里自定义的Servlet继承HttpServlet

1
2
3
4
5
6
//注册三大组件
@Bean
public ServletRegistrationBean myServlet(){
ServletRegistrationBean registrationBean = new ServletRegistrationBean(new MyServlet(),"/myServlet");
return registrationBean;
}

自定义Servlet代码

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MyServlet extends HttpServlet {

//处理get请求
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("Hello MyServlet");
}
}

FilterRegistrationBean

P.s. 自定义的过滤器实现Filter

1
2
3
4
5
6
7
@Bean
public FilterRegistrationBean myFilter(){
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new MyFilter());
registrationBean.setUrlPatterns(Arrays.asList("/hello","/myServlet"));
return registrationBean;
}

自定义过滤器代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MyFilter implements Filter {

@Override
public void init(FilterConfig filterConfig) throws ServletException {
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("MyFilter process...");
chain.doFilter(request,response);
}

@Override
public void destroy() {
}
}

ServletListenerRegistrationBean

P.s. 自定义监听器 实现ServletContextListener

1
2
3
4
5
@Bean
public ServletListenerRegistrationBean myListener(){
ServletListenerRegistrationBean<MyListener> registrationBean = new ServletListenerRegistrationBean<>(new MyListener());
return registrationBean;
}

自定义监听器代码

1
2
3
4
5
6
7
8
9
10
11
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("contextInitialized...web应用启动");
}

@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("contextDestroyed...当前web项目销毁");
}
}

以Gitee为例配置SSH实现免密码登录

常常需要操作远程的Git仓库,配置SSH免密登录可以让操作更加柔顺😁

操作步骤

1. 生成自己的SSH公钥和密钥

生成
1
ssh-keygen -t rsa -C "邮箱"

三次回车即可

2. 查看复制公钥

查看
1
cat ~/.ssh/id_rsa.pub

将此公钥添加到码云或其他Git托管的SSH

3. 测试是否成功

测试
1
ssh -T git@gitee.com