Spring Security使用详解6(自定义登录页、接口、结果)

Stella981
• 阅读 1143

在之前的所有样例中,登录表单一直都是使用 Spring Security 提供的默认登录页,登录成功后也是默认的页面跳转。有时我们想要使用自定义的登录页,或者在前后端分离的开发方式中,前后端的数据交互通过 JSON 进行,这时登录成功后就不是页面跳转了,而是一段 JSON 提示。下面通过样例演示如何进行登录表单的个性化配置。

六、自定义登录页面、登录接口、登录成功或失败的处理逻辑

1、样例代码

(1)首先修改 Spring Security 配置,增加相关的自定义代码:

  • 将登录页改成使用自定义页面,并配置登录请求处理接口,以及用户密码提交时使用的参数名。

  • 自定义了登录成功、登录失败的处理逻辑,根据情况返回响应的 JSON 数据。

    @Configuration public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter { // 指定密码的加密方式 @SuppressWarnings("deprecation") @Bean PasswordEncoder passwordEncoder(){ // 不对密码进行加密 return NoOpPasswordEncoder.getInstance(); } // 配置用户及其对应的角色 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("root").password("123").roles("DBA") .and() .withUser("admin").password("123").roles("ADMIN") .and() .withUser("hangge").password("123").roles("USER"); } // 配置 URL 访问权限 @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() // 开启 HttpSecurity 配置 .antMatchers("/db/").hasRole("DBA") // db/ 模式URL需DBA角色 .antMatchers("/admin/").hasRole("ADMIN") // admin/ 模式URL需ADMIN角色 .antMatchers("/user/").hasRole("USER") // user/ 模式URL需USER角色 .anyRequest().authenticated() // 用户访问其它URL都必须认证后访问(登录后访问) .and().formLogin() // 开启登录表单功能 .loginPage("/login_page") // 使用自定义的登录页面,不再使用SpringSecurity提供的默认登录页 .loginProcessingUrl("/login") // 配置登录请求处理接口,自定义登录页面、移动端登录都使用该接口 .usernameParameter("name") // 修改认证所需的用户名的参数名(默认为username) .passwordParameter("passwd") // 修改认证所需的密码的参数名(默认为password) // 定义登录成功的处理逻辑(可以跳转到某一个页面,也可以返会一段 JSON) .successHandler(new AuthenticationSuccessHandler() { @Override public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication auth) throws IOException, ServletException { // 我们可以跳转到指定页面 // resp.sendRedirect("/index"); // 也可以返回一段JSON提示 // 获取当前登录用户的信息,在登录成功后,将当前登录用户的信息一起返回给客户端 Object principal = auth.getPrincipal(); resp.setContentType("application/json;charset=utf-8"); PrintWriter out = resp.getWriter(); resp.setStatus(200); Map<String, Object> map = new HashMap<>(); map.put("status", 200); map.put("msg", principal); ObjectMapper om = new ObjectMapper(); out.write(om.writeValueAsString(map)); out.flush(); out.close(); } }) // 定义登录失败的处理逻辑(可以跳转到某一个页面,也可以返会一段 JSON) .failureHandler(new AuthenticationFailureHandler() { @Override public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException e) throws IOException, ServletException { resp.setContentType("application/json;charset=utf-8"); PrintWriter out = resp.getWriter(); resp.setStatus(401); Map<String, Object> map = new HashMap<>(); // 通过异常参数可以获取登录失败的原因,进而给用户一个明确的提示。 map.put("status", 401); if (e instanceof LockedException) { map.put("msg", "账户被锁定,登录失败!"); }else if(e instanceof BadCredentialsException){ map.put("msg","账户名或密码输入错误,登录失败!"); }else if(e instanceof DisabledException){ map.put("msg","账户被禁用,登录失败!"); }else if(e instanceof AccountExpiredException){ map.put("msg","账户已过期,登录失败!"); }else if(e instanceof CredentialsExpiredException){ map.put("msg","密码已过期,登录失败!"); }else{ map.put("msg","登录失败!"); } ObjectMapper mapper = new ObjectMapper(); out.write(mapper.writeValueAsString(map)); out.flush(); out.close(); } }) .permitAll() // 允许访问登录表单、登录接口 .and().csrf().disable(); // 关闭csrf } }

(2)在 resource/templates 目录下创建一个登录页面 login_page.html,内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/login" method="post">
        <div>
            <label>用户名</label>
            <input type="text" name="name"/>
        </div>
        <div>
            <label>密码</label>
            <input type="password" name="passwd"/>
        </div>
        <div>
            <input type="submit" value="登陆">
        </div>
    </form>
</body>
</html>

 (3)最后我们自定义一个 MVC 配置,并重写 addViewControllers 方法进行映射关系配置即可。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login_page").setViewName("login_page");
    }
}

2、运行测试

(1) 随便访问一个接口,浏览器会自动跳转到我们自定义的登录页面:

Spring Security使用详解6(自定义登录页、接口、结果)

(2)如果填写正确的用户名密码提交,则返回如下信息:

Spring Security使用详解6(自定义登录页、接口、结果)

(3)如果填写错误的用户名密码条,则返回如下信息:

Spring Security使用详解6(自定义登录页、接口、结果)

点赞
收藏
评论区
推荐文章
Chase620 Chase620
3年前
vue: 解决vuex页面刷新数据丢失问题
一、问题描述1、一般在登录成功的时候需要把用户信息,菜单信息放置vuex中,作为全局的共享数据。但是在页面刷新的时候vuex里的数据会重新初始化,导致数据丢失。因为vuex里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,vuex里面的数据就会被清空。2、我在一个组件(例如登录组件页面)中登录了后,其它页面要怎
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
liam liam
2年前
如何读取redis的手机号验证码数据,实现自动化登录测试
1、案例描述用户选择短信登录!发送短信后,后端接口逻辑已把验证码缓存在redis,!在apifox上定义对应下发登录短信接口,短信登录接口下载地址:这时候问题就来了,怎么样才能让apifox自动获取下发登录短信接口对应的手机号的验证码,自动填充到短信登录接口的code字段?2、解决思路方案一:后端通过接口返回验证码
马丁路德 马丁路德
3年前
小程序静默登录与维护自定义登录态
1.背景在小程序中,openid是一个用户对于一个小程序/公众号的标识,开发者可以通过这个标识识别出用户,就如同你的身份证一样。2.什么是静默登录?在普通的应用中,用户通过表单验证登录建立用户体系,这种常见的登录方式一般是通过登录页面表单进行登录,对用户来说是有感的。在小程序中,由于是基于微信,可以通过微信官方提供的API能力,使我们能够无感知得获取
菜园前端 菜园前端
1年前
JavaScript简单介绍
原文链接:什么是JavaScript?JavaScript是一种轻量级的编程语言(脚本语言)主要应用在前端方面。在Web层面上,就是给网页添加了交互的能力。比如点击某个按钮跳转到某个页面,点击登录按钮进行登录操作,渲染页面的数据等等。JS在前端领域是非常非
Easter79 Easter79
3年前
springMVC实现登陆
页面打开跳转到登陆页面登陆成功跳转到成功页面登陆失败再次返回登录页面,并增加提示信息1、首页跳转到登陆页面  Tomcat服务器启动时默认加载WEBINF下的index.jsp,可以通过修改xml配置的方式来改变Tomcat这一默认行为。这里使用springMVC来实现这个功能。  第一种实现
Stella981 Stella981
3年前
Nodejs,Express利用内置的session实现登录控制
varfilterrequire('./lib/filter');判断是否已经登录如果登录了则过去,否则跳转到登录页exports.authorizefunction(req,res,next){if(!req.session.user_id){res.redi
Wesley13 Wesley13
3年前
Asp.Net Forms认证在移动平台中遇到的一个问题以及调查过程
我们项目的网站的移动版是基于Asp.Net平台开发的,用户登录也是基于Asp.Net的Forms认证,在整个开发和测试过程中没有发现任何客户登录异常,但是发布后断断续续有用户反映在登录页面登录成功后跳转主页后,主页并没有识别登录用户,也即是Form认证失败。Asp.Net的Form认证大家应该有所了解,其内部的机制就是把用户数据加密后保存在一个基于cook
Stella981 Stella981
3年前
Spring Security使用详解7(注销登录配置)
默认情况下,SpringSecurity提供了注销接口是/logout,访问这个接口即可注销当前登录用户并且自动跳转到登录页。如果需要修改注销接口,或者想在注销时做一些业务逻辑,或者注销后不是跳转到登录页而是返回一段JSON提示,只需在一些简单配置即可。七、注销登录配置1、样例代码首先修改SpringSecurit