Spring 全家桶之 Spring Security(四)(下)

简介: Spring 全家桶之 Spring Security(四)

修改自定义安全配置CustSecurityConfig

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .antMatchers("/index.html","/login.html","/login","/404.html").permitAll()
            // 给url配置角色访问权限
            .antMatchers("/access/user").hasRole("USER")
            .antMatchers("/access/read").hasRole("READ")
            .antMatchers("/access/admin").hasRole("ADMIN")
            .anyRequest().authenticated()
            .and()
            .formLogin()
            // 指定使用自定义的登录界面
            .loginPage("/login.html")
            .loginProcessingUrl("/login")
            .failureUrl("/404.html") // 指定跳转的错误页面
            .and()
            .csrf().disable();
}
复制代码

重新启动应用,使用错误的用户名密码登录

91d503408e6244c7881151954f837345_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.gif

基于AJAX登录

在登录页面增加ajax代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>登陆</title>
    <style>
        //此处省略了样式代码,样式没有任何改变
    </style>
    <script type="text/javascript" src="/js/jquery-3.4.1.js"></script>
    <script type="text/javascript">
        $(function(){
            //juqery的入口函数
            $("#btnLogin").click(function(){
                var uname = $("#username").val();
                var pwd = $("#password").val();
                $.ajax({
                    url:"/login",
                    type:"POST",
                    data:{
                        "username":uname,
                        "password":pwd
                    },
                    dataType:"json",
                    success:function(resp){
                        alert(resp.msg)
                    }
                })
            })
        })
    </script>
</head>
<body>
<div class="main-body">
    <div class="login-main">
        <div class="login-top">
            <span>Login</span>
            <span class="bg1"></span>
            <span class="bg2"></span>
        </div>
        <form class="layui-form login-bottom">
            <div class="center">
                <div class="item">
                    <span class="icon icon-2"></span>
                    <input type="text" id="username" lay-verify="required"  placeholder="请输入登录账号" maxlength="24"/>
                </div>
                <div class="item">
                    <span class="icon icon-3"></span>
                    <input type="password" id="password" lay-verify="required"  placeholder="请输入密码" maxlength="20">
                    <span class="bind-password icon icon-4"></span>
                </div>
                <div class="layui-form-item" style="text-align:center; width:100%;height:100%;margin:0px;">
                    <button class="login-btn" lay-submit="" lay-filter="login" id="btnLogin">立即登录</button>
                </div>
            </div>
        </form>
    </div>
</div>
</body>
</html>
复制代码

取消了form表单提交数据,增加了ajax代码,并给username和password以及登录按钮增加了id属性,通过ajax代码获取属性的value,向后端发送 POST请求 新增handler包,增加successHandler即校验用户名密码成功后后执行的handler,及faliureHandler校验密码失败后执行的handler,增加@Component属性,将这两个Handler交割Spring管理

@Component
public class CustSuccessHandler implements AuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        // 登录的用户信息验证成功后执行的方法
        response.setContentType("text/json;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("{"msg":"登录成功"}");
        writer.flush();
        writer.close();
    }
}
复制代码
@Component
public class CustFailureHandler implements AuthenticationFailureHandler {
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        // 验证登录信息失败后执行的方法
        response.setContentType("text/json;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("{"msg":"验证失败"}");
        writer.flush();
        writer.close();
    }
}
复制代码

修改自定义安全配置

@Configuration
@EnableWebSecurity
public class CustSecurityConfig extends WebSecurityConfigurerAdapter {
    @Resource
    private UserDetailsService userDetailsService;
    @Resource
    private CustSuccessHandler custSuccessHandler;
    @Resource
    private CustFailureHandler custFailureHandler;
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 增加js静态资源的访问权限
                .antMatchers("/login.html","/index.html","/login","/js/**").permitAll()
                // 给url配置角色访问权限
                .antMatchers("/access/user").hasRole("USER")
                .antMatchers("/access/read").hasRole("READ")
                .antMatchers("/access/admin").hasRole("ADMIN")
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .successHandler(custSuccessHandler) //执行验证成功的handler
                .failureHandler(custFailureHandler) // 执行验证失败后的handler
                // 指定使用自定义的登录界面
                .loginPage("/login.html")
                .loginProcessingUrl("/login")
                .and()
                .csrf().disable();
    }
}
复制代码

使用@Resource注解将两个Handler注入,并且增加了js访问的白名单以及配置了验证成功和失败后的处理器

重启应用,并访问,如果页面显示加载jQyery失败,可以在Idea上Rebuild一下

image.png

页面报错ajax请求状态为已取消,并且无法获得相应

681600645d474974a38bcd1f26976ed5_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

解决这个问题的办法需要在ajax代码中增加一行代码,即可解决问题

async: false
复制代码

重新启动应用

72a01b4eefa841e69f9e7bac91854bf3_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.gif

返回JSON格式数据

增加jackson依赖

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.8</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.8</version>
</dependency>
复制代码

新增common包,增加一个Result类,用来表示返回的 JSON格式的数据

public class Result {
    private int code;
    private int error;
    private String msg;
    // 此处省略getter/setter方法
}    
复制代码

改造CustSuccessHandler和CustFailureHandler

@Component
public class CustSuccessHandler implements AuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        // 登录的用户信息验证成功后执行的方法
        response.setContentType("text/json;charset=utf-8");
        // 设置返回的Json格式的结果
        Result result = new Result();
        result.setCode(0);
        result.setError(1000);
        result.setMsg("登录成功");
        OutputStream outputStream = response.getOutputStream();
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.writeValue(outputStream,result);
        outputStream.flush();
        outputStream.close();
    }
}
复制代码
@Component
public class CustFailureHandler implements AuthenticationFailureHandler {
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        // 验证登录信息失败后执行的方法
        response.setContentType("text/json;charset=utf-8");
        // 设置返回的Json格式的结果
        Result result = new Result();
        result.setCode(0);
        result.setError(1001);
        result.setMsg("登录失败");
        OutputStream outputStream = response.getOutputStream();
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.writeValue(outputStream,result);
        outputStream.flush();
        outputStream.close();
    }
}
复制代码

重启应用,即可返回Json格式数据


相关文章
|
28天前
|
JSON 安全 Java
什么是JWT?如何使用Spring Boot Security实现它?
什么是JWT?如何使用Spring Boot Security实现它?
120 5
|
5月前
|
安全 Java 数据安全/隐私保护
使用Spring Security实现细粒度的权限控制
使用Spring Security实现细粒度的权限控制
|
5月前
|
安全 Java 数据库
实现基于Spring Security的权限管理系统
实现基于Spring Security的权限管理系统
|
5月前
|
安全 Java 数据安全/隐私保护
解析Spring Security中的权限控制策略
解析Spring Security中的权限控制策略
|
6月前
|
JSON 安全 Java
Spring Security 6.x 微信公众平台OAuth2授权实战
上一篇介绍了OAuth2协议的基本原理,以及Spring Security框架中自带的OAuth2客户端GitHub的实现细节,本篇以微信公众号网页授权登录为目的,介绍如何在原框架基础上定制开发OAuth2客户端。
239 4
Spring Security 6.x 微信公众平台OAuth2授权实战
|
6月前
|
存储 安全 Java
Spring Security 6.x OAuth2登录认证源码分析
上一篇介绍了Spring Security框架中身份认证的架构设计,本篇就OAuth2客户端登录认证的实现源码做一些分析。
277 2
Spring Security 6.x OAuth2登录认证源码分析
|
6月前
|
安全 Java 数据安全/隐私保护
Spring Security 6.x 一文快速搞懂配置原理
本文主要对整个Spring Security配置过程做一定的剖析,希望可以对学习Spring Sercurity框架的同学所有帮助。
330 5
Spring Security 6.x 一文快速搞懂配置原理
|
6月前
|
安全 Java API
Spring Security 6.x 图解身份认证的架构设计
【6月更文挑战第1天】本文主要介绍了Spring Security在身份认证方面的架构设计,以及主要业务流程,及核心代码的实现
99 1
Spring Security 6.x 图解身份认证的架构设计
|
5月前
|
安全 Java 数据安全/隐私保护
使用Spring Security实现细粒度的权限控制
使用Spring Security实现细粒度的权限控制
|
5月前
|
安全 Java 数据安全/隐私保护
使用Java和Spring Security实现身份验证与授权
使用Java和Spring Security实现身份验证与授权