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");    }

这里配置的接口须要本人实现其逻辑。