SpringSecurity前后端分离自定义登录处理

自定义登录成功处理(前后端分离开发)

有时候页面跳转并不能满足我们,特别是在前后端分离开发中就不需要成功之后跳转页面。只需要给前端返回一个JSON通知登录成功还是失败与否。这个时候可以通过自定义AuthenticationSucccessHandler 实现。

public interface AuthenticationSuccessHandler {
    
    default void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException, ServletException {
        this.onAuthenticationSuccess(request, response, authentication);
        chain.doFilter(request, response);
    }

    void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException;
}

根据接口的描述信息,也可以得知登录成功会自动回调这个方法,进一步查看它的默认类实现,你会发现successForwardUrl、defaultSuccessUrl也是由它的子类实现的。

在这里插入图片描述

1.实现AuthenticationSucessHandler,自定义成功之后处理。

public class MyAuthenticationSuccessHandlerConfig implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        Map<String,Object> result = new HashMap<>();
        result.put("msg","登录成功!");
        result.put("status",200);
        result.put("authentication",authentication);
        response.setContentType("application/json;charset=UTF-8");
        String string = new ObjectMapper().writeValueAsString(result);
        response.getWriter().println(string);
    }
}

2.配置AuthenticationSuccessHandler

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
               	...
                .and()
                .formLogin()
                ...
                //认证成功时处理,前后端分离解决方案
                .successHandler(new MyAuthenticationSuccessHandlerConfig())
                .and()
                //禁止 csrf 跨站请求保护
                .csrf().disable();
    }
}

3.浏览器返回json格式数据

在这里插入图片描述

显示登录失败信息

经过源码debug分析可知,Security在登录失败之后会将异常信息存储到request 作用域或者session中 key为SPRING_SECURITY_LAST_EXCEPTION常量中。

  • failureForwardUrl() forward 将信息存在request作用域中
  • failureUrl() redirect 将信息存在session作用域中

在这里插入图片描述

  • 显示异常信息
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
</head>
<body>
    <h2>
        <div th:text="${SPRING_SECURITY_LAST_EXCEPTION}"></div>
    </h2>
   	...
</body>
</html>

自定义登录失败处理

和自定义登录成功一样,Spring Security 同样为前后端分离开发提供了登录失败的处理,这个类就是AuthenticationFailureHandler。源码为:

public interface AuthenticationFailureHandler {

   /**
    * Called when an authentication attempt fails.
    * @param request the request during which the authentication attempt occurred.
    * @param response the response.
    * @param exception the exception which was thrown to reject the authentication
    * request.
    */
   void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
         AuthenticationException exception) throws IOException, ServletException;

}

根据接口的描述信息,也可以得知登录失败会自动回调这个方法,进一步查看它的默认实例,会发现failureUrl、failureForwardUrl也是由它的子类实现的。

AuthenticationFailureHandler关系图

在这里插入图片描述

  • 自定义AuthenticationFailureHandler实现
 public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
     @Override
     public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
         Map<String,Object> result = new HashMap<>();
         result.put("msg","登录失败!"+exception.getMessage());
         result.put("status",500);
         response.setContentType("application/json;charset=UTF-8");
         String string = new ObjectMapper().writeValueAsString(result);
         response.getWriter().println(string);
     }
 }
 
  • 配置AuthenticationFailureHandler
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
         		...
                .anyRequest().authenticated()
                .and()
                .formLogin()
            	...
                .failureHandler(new MyAuthenticationFailureHandler())
                .and()
                //禁止 csrf 跨站请求保护
                .csrf().disable();
    }
}
  • 访问登录,输入错误密码

在这里插入图片描述

注销登录

Spring Security中也提供了默认的注销登录配置,在开发时也可以按照自己需求对注销进行个性化定制。

  • 开启注销登录(默认开启)
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                ...
                .anyRequest().authenticated()
                .and()
                .formLogin()
                ...
                .and()
                .logout()
                //指定注销登录的URl,默认的请求方式是GET
                .logoutUrl("/logout")
                //是否让当前session失效
                .invalidateHttpSession(true)
                //清除认证信息
                .clearAuthentication(true)
                //注销登录跳转页面
                .logoutSuccessUrl("/login.html")
                .and()
                //禁止 csrf 跨站请求保护
                .csrf().disable();
    }
}
  • 通过logout()方法开启注销配置
  • logoutUrl指定退出登录请求地址,默认请求是GET请求,路径为/logout
  • invalidateHttpSession退出时是否是session失效,默认值为true
  • clearAuthentication 退出时是否清除认证信息,默认值为true
  • logoutSuccessUrl退出登录时跳转地址

配置多个注销登录请求

如果项目中有需要,开发者还可以配置多个注销登录的请求,同时还可以指定请求的方法:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                ...
                .anyRequest().authenticated()
                .and()
                .formLogin()
                ...
                .and()
                .logout()
                .logoutRequestMatcher(new OrRequestMatcher(
                        new AntPathRequestMatcher("/aa","GET"),
                        new AntPathRequestMatcher("/bb","POST")
                ))
                ...
                .and()
                //禁止 csrf 跨站请求保护
                .csrf().disable();
    }
}
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
前后端分离的架构中使用Spring Security,需要进行以下几个步骤: 1. 前端登录页面:前端需要提供一个登录页面,用于用户输入用户名和密码。这个页面可以是一个简单的HTML表单或者使用前端框架(如React、Vue)进行构建。 2. 前端登录请求:前端需要发送登录请求,将用户输入的用户名和密码发送给后端。这个请求可以是一个POST请求,将用户凭证(如用户名和密码)以JSON格式发送给后端。 3. 后端验证登录信息:后端需要接收前端发送的登录请求,并使用Spring Security对用户的凭证进行验证。可以通过自定义实现`UserDetailsService`接口来提供用户信息,并通过`AuthenticationManager`进行认证。 4. 后端生成Token:如果登录信息验证成功,后端可以生成一个Token,并返回给前端。这个Token可以使用JWT(JSON Web Token)或者其他类似的机制进行生成。 5. 前端保存Token:前端需要将后端返回的Token保存起来,一般通过将Token存储在浏览器的LocalStorage或者Cookie中。 6. 后续请求携带Token:在后续的请求中,前端需要将保存的Token携带在请求的Header中,一般使用`Authorization`字段,值为`Bearer <Token>`。 7. 后端验证Token:后端在接收到前端的请求后,需要验证请求中携带的Token的有效性。可以通过编写一个自定义Spring Security过滤器来实现Token的验证。 8. 权限控制:使用Spring Security的权限控制机制,可以对不同的URL进行权限配置,并通过注解或者配置的方式限制用户访问某些资源。 通过以上步骤,就可以在前后端分离的架构中使用Spring Security进行用户认证和权限控制。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值