共计 4118 个字符,预计需要花费 11 分钟才能阅读完成。
Java Web 我的项目的权限治理框架,目前有两个比拟成熟且应用较多的框架,Shiro 和 Spring Security,Shiro 比 Spring Security 更加轻量级,然而须要手动配置的货色较多,Spring Security 和 Spring 集成更好,甚至间接适配了 Spring Boot。
本文集体博客地址:https://www.abeille.top/posts/detail/208291JMJ
一、最简略的应用:
1.1、配置及应用
要应用 Spring Security 首先要引入依赖,Spring-boot 曾经有了集成,间接引入 spring-boot-statr-security 依赖包即可:
<!-- spring security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
演示我的项目应用的是 Spring boot 2.1.5 版本,所以退出依赖后,会主动获取 Spring Security 5.1.5 版本的 Jar 包:
而后,就没有而后了,一个根本的 Spring Security 曾经有了,而后关上浏览器,拜访 http://localhost:8080,神奇的 …
Spring Security 曾经默认做了一些配置,并且创立一个简略的登录页面,那这个页面事怎么来的?通过查看相干文档和源码来一探到底。
那什么都没有配置,从哪开始开始看呢?
1.2、剖析原理
1.2.1、登录页面:
个别不知从何动手,就看官网文档里是如何做的,官网的文档和 api 是最好最残缺的介绍和参考,点击链接查看官网文档地址 (https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#jc-oauth2login),或者通过 Google 搜寻 spring security,在后果中点击 Spring Security Reference,点击进入页面,而后就能够看到对于 Spring Security 的文档;
通过查看文档发现,WebSecurityConfigurerAdapter 提供的默认的配置,那就来看看这个抽象类,在这个抽象类中,又一个办法配置了 formLogin(),这个办法内容如下:
查看 formLogin() 源码,跳转到 HttpSecurity 类中,这个办法返回一个 FormLoginConfigurer<HttpSercurity> 类型的数据。再持续来看看这个 FormLoginConfigurer,在 FormLoginConfigurer 中有个 initDefaultLoginFilter() 办法:
这个办法,初始化一个默认登录页的过滤器,能够看到第一句代码,默认的过滤器是 DefaultLoginPageGeneratingFilter,上面是设置一些必要的参数,进入到这个过滤器中:
在形容中能够看到,如果没有配置 login 页,这个过滤器会被创立,而后看 doFilter() 办法:
登录页面的配置是通过 generateLoginPageHtml() 办法创立的,再来看看这个办法内容:
private String generateLoginPageHtml(HttpServletRequest request, boolean loginError,
boolean logoutSuccess) {
String errorMsg = "none";
// ...
if (formLoginEnabled) {sb.append("<h3>Login with Username and Password</h3>");
sb.append("<form name='f'action='").append(request.getContextPath())
.append(authenticationUrl).append("'method='POST'>\n");
sb.append("<table>\n");
sb.append("<tr><td>User:</td><td><input type='text'name='");
sb.append(usernameParameter).append("'value='").append("'></td></tr>\n");
sb.append("<tr><td>Password:</td><td><input type='password'name='")
.append(passwordParameter).append("'/></td></tr>\n");
if (rememberMeParameter != null) {sb.append("<tr><td><input type='checkbox'name='")
.append(rememberMeParameter)
.append("'/></td><td>Remember me on this computer.</td></tr>\n");
}
sb.append("<tr><td colspan='2'><input name=\"submit\"type=\"submit\"value=\"Login\"/></td></tr>\n");
renderHiddenInputs(sb, request);
sb.append("</table>\n");
sb.append("</form>");
}
// ...
}
至此,默认登录页及配置,曾经能够分明了。
1.2.2、登录用户及明码:
在我的项目启动的日志中,能够发现有这样一条信息:
能够看到,主动配置类是 UserDetailsServiceAutoConfiguration,明码是 cf73184c-e8f2-48d8-9ce3-4413e3943f19,当初晓得了明码,那用户名是什么还不晓得,进入到 UserDetailsServiceAutoConfiguration 中去看看。
在这个 UserDetailsServiceAutoConfiguration 类的形容中能够晓得,这个类是设置一些 Spring Security 相干默认的主动配置,把 InMemoryUserDetailsManager 中得 user 和 password 信息设置为默认得用户和明码,能够通过提供的 AuthenticationManager、AuthenticationProvider 或者 UserDetailsService 的 bean 来笼罩默认的主动配置信息。
能够看到,日志中那句明码打印的是从图片中圈进去的这条语句打印的,在这个办法下面有一个 inMemoryUserDetailsManager() 办法,返回一个新的带有 UserDetials 信息参数结构的 InMemoryUSerDetailsManager 对象:
能够看到,第一个参数是 User.withUsername(user.getName()),这个 user.getName() 的 user 对象是下面 SecurityProperties.User 类型的,通过 SecurityProperties 对象中获取的,首先看下 SecurityProperties 类:
通过配置文件中的,前缀为 spring.security 的配置能够扭转默认配置信息,再看看 SecurityProperties 的 getUser() 办法:
=>=>
通过一步步的跟踪,发现默认的用户名是 user。当初须要定义一个胜利之后返回信息的 Controller,并写一个办法:
@Controller
public class IndexController {@RequestMapping("/")
public String index() {return "/login";}
}
胜利登录后,DispatcherServlet 会将路由定位到“/”门路下,咱们配置“/”再跳转到“/login”门路。
@RequestMapping("/login")
@ResponseBody
public Boolean login() {return false;}
去默认的登录页面尝试一下,输出用户名:user,明码:(每次启动都会从新生成一个 UUID 的字符串),登录胜利了,跳转到了 RequestMapping(“/”) 而后又跳转至 RequestMapping(“/login”),并返回后果,下面的提示信息说 XML 解析的问题,查了材料,在 IE 中是没有问题的,能够间接显示后果 false,而谷歌显示 XML 类型的信息:
1.3、批改默认配置的登录页和申请解决接口:
批改默认的 Security 配置须要继承 WebSecurityConfigurerAdapter 类,而后覆写 config(HttpSecurity http) 办法;
1.3.1、批改登录页:
定制本人开发的登录页的,只须要调用 formLogin().loginPage(“/customLogin”) 即可。
@Override
protected void configure(HttpSecurity http) throws Exception {http.formLogin().loginPage("/customLogin");
}
留神:loginPage 配置会通过模板解析即 TemplateResolver 解决,所以能写.ftl 或者.html 后缀。
1.3.1、批改登录申请:
默认的解决接口为 login,如果想批改也是能够的,通过 formLogin().loginProcessingUrl(“/singin”) 可配置。
@Override
protected void configure(HttpSecurity http) throws Exception {http.formLogin().loginProcessingUrl("/signin");
}
这里配置的接口须要本人实现其逻辑。