SpringSecurity02
操作
放行首页和静态资源
- 在配置类中重写父类的configure(HttpSecurity http)方法.
@Override protected void configure(HttpSecurity security) throws Exception { security .authorizeRequests() //对请求进行授权 .antMatchers("/index.jsp", "/layui/**") //使用ant风格设置要授权的url地址 .permitAll() //允许使用上面设置的全部请求 .anyRequest() //其他未设置的全部请求 .authenticated() //需要认证 ; }
- 在设置授权信息时, 范围小的放前面, 范围大的放后面, 不然小范围的会被大范围的覆盖掉.
- 效果: 未登录的请求访问需要登录的请求时会看到403页面.
未认证的请求跳转到登录页
-
@Override protected void configure(HttpSecurity security) throws Exception { security //....省略部分操作 .and() .formLogin() //使用表单形式登录 .loginPage("/index.jsp") //指定登录页面(如果不写会去springSecurity默认的登录页) .loginProcessingUrl("/do/login.html") //指定提交登录表单的地址 ; }
- 关于loginPage(String url)方法的说明
- 在指定登录页面的同时会影响到"提交登录表单的地址", "退出登录地址", "登陆失败地址", 比如url为"/index.jsp"
- /index.jsp GET 去登陆页面
- /index.jsp POST提交登录表单的地址
- /index.jsp?error GET 登陆失败地址
- /index.jsp?logout GET 退出登录
- loginnProcessingUrl("xxx")
- 该方法指定登录地址后, 就会覆盖loginPage()中设置的默认值 /index.jsp POST
设置登录系统的账号和密码(内存中)
- 思路
- 页面设置
<p>${SPRING_SECURITY_LAST_EXCEPTION.message}</p> <form action="${pageContext.request.contextPath}/do/login.html" method="post"> <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> ...... </form>
- <p>标签中是错误信息.
- 这里必须设置_csrf防止跨站请求伪造
- 账号密码的请求参数名
- 账号默认请求参数名: username
- 密码默认请求参数名: password
- 如果要定制请求参数名, 用usernameParameter()和passwordParameter()方法
- 设置登录成功后去的页面: defaultSuccessUrl("xxx")
@Override protected void configure(HttpSecurity security) throws Exception { security //....省略部分操作 .loginProcessingUrl("/do/login.html") //指定提交登录表单的地址 .usernameParameter("loginAcct") //定制登录账号请求参数名 .passwordParameter("userPswd") //定制登陆密码请求参数名 .defaultSuccessUrl("/main.html") //设置登录后默认前往的url地址 ; }
- 设置登录账号密码
- 要重写父类的configure(AuthenticationManagerBuilder auth)
@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() //在内存中完成账号和密码的检查 .withUser("Tom") //指定账号 .password("123456") //指定密码 .roles("ADMIN") //指定当前用户角色 .and() .withUser("Jerry") .password("123456") .authorities("DELETE") //指定当前用户的权限 ; }
- 如果不设置roles()或authorities()方法(不提供角色或权限), 会出现Cannot pass a null GrantedAuthority collection错误.
- 用意: 仅仅有账号和密码不够, 还必须具备访问特定资源的角色或权限才能登入.
- 要重写父类的configure(AuthenticationManagerBuilder auth)
_csrf是如何防止跨站请求伪造的.
- Cross-site request forgery: 跨站请求伪造
- 在我们启动springSecurity的CSRF功能后, 如果发送登录请求时没有携带_csrf值, 会报错
- 跨站请求的防御分析
用户的注销
- 通过调用HttpSecurity对象的一系列方法设置注销.
- logout(): 开启注销功能.
- logoutUrI(): 自定义注销功能的URL地址.
- 如果csrf功能没有被禁用, 那么退出请求必须携带CSRF的token值(只能POST方式), 如果禁用了csrf功能, 则任何请求方式都可以.
- logoutSuccessUrl()方法:退出成功后前往的URL地址
- addLogoutHandler()方法:添加退出处理器
- logoutSuccessHandler()方法:退出成功处理器
- 禁用csrf后的注销
- 页面操作非常简单
<a href="${pageContext.request.contextPath}/do/logout.html">退出</a>
- 控制代码
@Override protected void configure(HttpSecurity security) throws Exception { security //...略部分代码 .and() .csrf() .disable() //禁用csrf功能 .logout() //开启退出功能 .logoutUrl("/do/logout.html") //指定处理退出请求的url地址 .logoutSuccessUrl("/index.jsp") //退出成功后前往的页面 ; }
- 页面操作非常简单
- 启用csrf后的注销
- 页面比较复杂: 要通过点击超链接, 绑定一个单击响应函数, 再转换为提交一个表单
<li class="layui-nav-item"> <form id="logoutForm" action="${pageContext.request.contextPath }/do/logout.html" method="post"> <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> </form> <a id="logoutAnchor" > 退出 </a> <script type="text/javascript"> window.onload = function() { //给超链接的DOM对象绑定 单击响应函数. document.getElementById("logoutAnchor").onclick = function() { //提交包含csrf参数的表单 document.getElementById("logoutForm").submit(); //取消超链接的默认行为 return false; }; }; </script> </li>
- 控制代码
@Override protected void configure(HttpSecurity security) throws Exception { security //...略部分代码 .and() .logout() //开启退出功能 .logoutUrl("/do/logout.html") //指定处理退出请求的url地址 .logoutSuccessUrl("/index.jsp") //退出成功后前往的页面 ; }
- 页面比较复杂: 要通过点击超链接, 绑定一个单击响应函数, 再转换为提交一个表单