SpringBoot + SpringSecurity 权限身份安全验证异步ajax登录验证后又跳回security自带的login页面问题

最近公司项目快结束了,基本业务都已跑通,现在需要将security安全框架的身份权限验证加入进去。但是在加入以后,自定义登录页面登录成功以后,并不会走继承于UserDetails的自定义类方法,那么security也就获取不到申请者的账号密码信息,也就没法进行身份权限的验证。所以每次自定义的控制层登录验证成功以后都会再次跳入自带的login页面,需要再登录一次才行。一开始以为是自己异步申请的问题,查阅了网上许多相关资料,尝试了许多办法,有说继承SimpleUrlAuthenticationSuccessHandler的,有说因为是ajax请求,所以还需要写个判断是否是ajax申请的。尝试完以后,对于我来说都没有解决我的问题。

问题描述:

security框架,配置了loginPage以后便不断的被拦截重定向至loginPage所配置的页面,不配置loginPage,仅配置defaultSuccessUrl的话,在经过自定义的登录验证后,便会进入到security框架自带的login页面。

解决办法:

  1. 首先是登录页面:
<body>
<form class="layui-form" id="loginSubmit" method="post" th:action="@{/sys/base/home}" action="sys/base/home">



    <!--账号-->
    <div class="layui-form-item layui-form-text">
        <div class="layui-input-inline">
            <input name="username" id="acCode" class="layui-input" type="text" placeholder="请输入账号" autocomplete="off"
                   lay-verify="required" lay-reqtext="账号是必填项,不能为空!!!"/>
            <i class="layui-icon  layui-icon-username" style="position: absolute;top:8px;right: 8px;"></i>

        </div>

    </div>
    <!--密码-->
    <div class="layui-form-item layui-form-text">
        <div class="layui-input-inline">
            <input name="password" id="acPwd" class="layui-input" type="password" placeholder="请输入密码" autocomplete="off"
                   lay-verify="required" lay-reqtext="密码是必填项,不能为空!!!"/>
            <i class="layui-icon  layui-icon-password" style="position: absolute;top:8px;right: 8px;"></i>
        </div>
    </div>

    <!--验证码-->
    <div class="layui-form-item layui-form-text grid-demo grid-demo-bg2">
        <div class="layui-input-inline">
            <input name="acYZM" id="acYZM" class="layui-input" type="text" placeholder="请输入验证码" autocomplete="off"
                   lay-verify="required" lay-reqtext="验证码是必填项,不能为空!!!" />
            <i class="layui-icon  layui-icon-vercode" style="position: absolute;top:8px;right: 8px;"></i>
        </div>
    </div>
    <!--验证码图片-->
    <div class="layui-form-item layui-form-text grid-demo grid-demo-bg2">
        <div class="layui-input-inline">
            <a href="javascript:getVerifiCode()">
                <img id="yzm_img"  title="点击刷新验证码" src="http://localhost:8099/sysLogin/getVerifiCode"/>
            </a>
        </div>
    </div>

    <!--登录按钮-->
    <div class="layui-form-item layui-form-text grid-demo grid-demo-bg2">
        <div class="layui-input-inline">
            <input type="button" class="layui-btn layui-btn-lg" lay-filter="login" lay-submit="" value="登录"/>
        </div>
    </div>
</form>
</body>
  1. js部分代码
<script type="text/javascript" th:inline="javascript">
    layui.use(['form'], function () {
        var form = layui.form;
        form.on('submit(login)', function (data) {
            var data = {"acCode": $("#acCode").val(), "acPwd": $("#acPwd").val(), "acYZM": $("#acYZM").val()};
            $.ajax({
                type: "post",
                url: '/sys/base/acctLogin',
                data: JSON.stringify(data),
                datatype: 'json',
                contentType: 'application/json',
                success: function (result) {
                    if (成功的情况) {
                       setTimeout(layer.msg('登录成功'), 3000);
                        $("#loginSubmit").submit();
                    } else 失败的情况 {
                        
                },
                error: function () {
                    alert("出错,重新跳转故障登记页面");
                    location.href = '/sysLogin/login'
                }
            })
        });
    });
</script>

因为公司没有写前端的,所以使用了layui来写前端页面。

这里说明一下,我是在异步走自定义的控制层方法来判断用户登录成功与否,以及校验验证码的。返回的是一个json对象,传递时后台用对象接收。后台控制层代码就不放了。自己写一下问题不大的。

  1. securityConfig配置:
@Configuration
@EnableGlobalMethodSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
		.
		./*此处代码省略,只放上主要配置*/
		.
 @Bean
    UserDetailsService customUserService() { // 注册UserDetailsService 的bean
        return new UserAuthService();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .headers().frameOptions().disable()
                .and()
                // 禁用CSRF保护
                .csrf().disable().authorizeRequests()
                .antMatchers("将免验证的路径进行开放").permitAll()
                // 任何访问都必须授权
                .anyRequest().authenticated()
                // 登录路径
                .and().formLogin()
                .loginPage("被拦截后跳转的页面").permitAll()
                .loginProcessingUrl("验证后跳转的页面")
                .defaultSuccessUrl("/默认成功后跳转的页面")
				.permitAll() //登录页面用户任意访问
//               .usernameParameter("acCode").passwordParameter("acPwd")
                // 登陆成功后的处理,因为是API的形式所以不用跳转页面
//                .successHandler(new RestAuthenticationSuccessHandler())
                // 登陆失败后的处理
                .failureHandler(new RestAuthenticationFailureHandler()).and()
                // 登出后的处理
                .logout().logoutSuccessHandler(new RestLogoutSuccessHandler());
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 临时屏蔽加密功能
        auth.userDetailsService(customUserService());
        // .passwordEncoder(passwordEncoder());
    }


    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(将需要开放的配置在内);
    }
}
  1. 实现UserDetailsService类

/**
 * 用户鉴权处理
 */
@Component
public class UserAuthService implements UserDetailsService {
    /**
     * 用户账户服务
     */
    @Autowired
    private SysBaseService service;

    /**
     * 加载用户信息
     * {@inheritDoc}
     */
    @Override
    public UserDetails loadUserByUsername(String userCode) throws UsernameNotFoundException {
																			//此处传来的是用户账号   
        if (!StringUtils.isEmpty(userCode)) {
            /**
             * 获得账户相关信息
             */
            SysAccountPro acct = service.getAcctByCode(userCode);
            if (acct != null) {
          这里面判断用户信息啥的,如果用户验证通过,怎返回一个newUser对象。
                }
                return new User(acct.getAcCode(), acct.getAcPwd(), grantedAuthorities);
            } else {
            
            }
        } else {
            
        }
    }

基本上整体所需要配置的就是这些了,主要在于异步的地方我最后其实还是使用了提交表单的形式。异步去判断账号密码,验证码之类的问题,由提交表单来触发security的验证机制。
如有错误,欢迎纠正。

万般皆下品,唯有读书高。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

97年的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值