SpringBoot前后分离项目实现自定义登录拦截

简介: 版权声明:本文首发 http://asing1elife.com ,转载请注明出处。 https://blog.csdn.net/asing1elife/article/details/82696896 ...
版权声明:本文首发 http://asing1elife.com ,转载请注明出处。 https://blog.csdn.net/asing1elife/article/details/82696896

SpringBoot前后分离项目实现自定义登录拦截

通常的 shiro 登录拦截对于 /login 操作可设置为 authc 模式,但前后分离的项目直接设置会导致无法获取登录信息

更多精彩

自定义登录拦截的实现

  1. 要实现自定义的登录拦截是继承 FormAuthenticationFilter 接口
  2. 对接口中的 onLoginSuccessonLoginFailure 重写
    • 从而根据登录成功和失败进行不同的操作记录
public class LoginFormAuthenticationFilter extends FormAuthenticationFilter {

  // springBoot中存在与配置类的service类需要提供get/set方法手动收入,如果使用@Autowired会导致报错
    private MemberLoginRecordServiceImpl memberLoginRecordService;

    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, 
ServletRequest request, ServletResponse response) throws Exception {
        // 处理会员登录成功操作
        memberLoginRecordService.doAfterSuccessfullyLogin(request, subject);

        return super.onLoginSuccess(token, subject, request, response);
    }

    @Override
    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, 
ServletRequest request, ServletResponse response) {
        return super.onLoginFailure(token, e, request, response);
    }

    public MemberLoginRecordServiceImpl getMemberLoginRecordService() {
        return memberLoginRecordService;
    }

    public void setMemberLoginRecordService(MemberLoginRecordServiceImpl memberLoginRecordService) {
        this.memberLoginRecordService = memberLoginRecordService;
    }
}

将重写的拦截器注入到 shiro 配置中

@Configuration
@ConditionalOnWebApplication
public class ShiroConfiguration extends BaseShiroConfiguration {

  ...

    // 手动注入自定义拦截器需要用到的service
    // 注入该service即可,service内部的其他类可实现自动注入
    @Bean
    public MemberLoginRecordServiceImpl memberLoginRecordService() {
        return new MemberLoginRecordServiceImpl();
    }

    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) throws Exception {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 指定登录链接
        shiroFilterFactoryBean.setLoginUrl("/login");

        Map<String, Filter> filters = new LinkedHashMap<String, Filter>();

        // 配置自定义表单拦截器
        LoginFormAuthenticationFilter authcFilter = new LoginFormAuthenticationFilter();
        authcFilter.setRememberMeParam("rememberMe");
        // 注入上述引用的service类
        authcFilter.setMemberLoginRecordService(memberLoginRecordService());
        // 选择指定拦截器的规则
        filters.put("authc", authcFilter);

        shiroFilterFactoryBean.setFilters(filters);

        // 配置不同接口规则
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        // 登出操作由shiro管理
        filterChainDefinitionMap.put("/logout", "anon");
        // 以下规则可直接访问
        filterChainDefinitionMap.put("/api/portals/**", "anon");

        // 以下规则需要认证访问
        filterChainDefinitionMap.put("/login", "authc");
        filterChainDefinitionMap.put("/api/**", "authc");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return shiroFilterFactoryBean;
    }
}

以上方式在前后分离项目中会出现的问题

  1. 由于项目是前后分离的,前端发起的直接是访问 loginController 的请求
  2. 该请求由于配置了 authc 规则,则需要认证才能访问
  3. 所以就导致以上配置方式会直接报错
  4. 而如果将 /login 请求配置为 anon 规则,则会导致登录操作无法被自定义表单拦截器拦截

解决方式

  1. 重写 FormAuthenticationFilter 接口的 onAccessDenied 方法
  2. 判断当前访问该规则的请求是否为登录请求
  3. 如果是登录请求则再次判断是否为登录提交请求 this.isLoginRequest
    • 因为正常的登录请求中会存在一个访问登录页面和提交登录表单两个操作
    • 而前后分离项目发起的必然是提交登录表单 this.isLoginSubmission
  4. 如果不是登录请求则返回 false
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
    if (this.isLoginRequest(request, response) && this.isLoginSubmission(request, response)) {
        return true;
    }

    return false;
}
目录
相关文章
|
7天前
|
Java Linux
Springboot 解决linux服务器下获取不到项目Resources下资源
Springboot 解决linux服务器下获取不到项目Resources下资源
|
15天前
|
Java API Spring
SpringBoot项目调用HTTP接口5种方式你了解多少?
SpringBoot项目调用HTTP接口5种方式你了解多少?
58 2
|
15天前
|
前端开发 JavaScript Java
6个SpringBoot 项目拿来就可以学习项目经验接私活
6个SpringBoot 项目拿来就可以学习项目经验接私活
28 0
|
27天前
|
前端开发 Java 关系型数据库
SpringBoot+MyBatis 天猫商城项目
SpringBoot+MyBatis 天猫商城项目
47 1
|
29天前
|
JSON JavaScript 前端开发
解决js中Long类型数据在请求与响应过程精度丢失问题(springboot项目中)
解决js中Long类型数据在请求与响应过程精度丢失问题(springboot项目中)
32 0
|
18天前
|
Java Maven 微服务
springboot项目开启远程调试-jar包
springboot项目开启远程调试-jar包
16 0
|
1月前
|
缓存 前端开发 Java
【二十八】springboot之通过threadLocal+参数解析器实现同session一样保存当前登录信息的功能
【二十八】springboot之通过threadLocal+参数解析器实现同session一样保存当前登录信息的功能
28 1
|
13天前
|
Java 测试技术 数据库
基于SpringBoot+HTML实现登录注册功能模块
基于SpringBoot+HTML实现登录注册功能模块
|
8天前
|
JSON 前端开发 Java
Springboot前后端分离项目统一封装返回结果
Springboot前后端分离项目统一封装返回结果
|
26天前
|
Java Unix Shell
springboot项目重启的shell命令
springboot项目重启的shell命令
13 0