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,并写一个办法:
@Controllerpublic 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"); }
这里配置的接口须要本人实现其逻辑。