spring-boot整合spring-security实现简单登录(ajax登录实现)

个人技术网站 欢迎关注

平常再做一些项目时,有些项目并不需要复杂的登录权限验证 只需要简单登录权限验证(保证安全可靠的前提下),找来找去只有spring-security最适合不过了,在spring-boot下配置简单 便捷 快速 能满足基本的登录权限控制需求。

第一步:引入spring-security maven依赖

<!-- 整合spring security -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-security</artifactId>
</dependency>

第二步:编写spring-security配置类 WebSecurityConfig

package com.xcloud.currency.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.web.filter.CharacterEncodingFilter;

/**
 * Xcloud-Api By IDEA
 * Created by LaoWang on 2018/8/28.
 * WebSecurityConfigurerAdapter:重写它的方法来设置一些web的安全
 */
@Configuration
@EnableWebSecurity // 注解开启Spring Security的功能
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    MyAuthenctiationFailureHandler myAuthenctiationFailureHandler;

    @Autowired
    MyAuthenctiationSuccessHandler myAuthenctiationSuccessHandler;

    @Override
    public void configure(WebSecurity web) throws Exception {
        //解决静态资源被拦截的问题
        web.ignoring().antMatchers("/css/**");
        web.ignoring().antMatchers("/js/**");
        web.ignoring().antMatchers("/images/**");
        web.ignoring().antMatchers("/lib/**");
        web.ignoring().antMatchers("/fonts/**");
        web.ignoring().antMatchers("/lang/**");
        web.ignoring().antMatchers("/login/**");
        web.ignoring().antMatchers("/login.html");
        //解决服务注册url被拦截的问题
        web.ignoring().antMatchers("/swagger-resources/**");
        web.ignoring().antMatchers("/v2/**");
        web.ignoring().antMatchers("/**/*.json");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .failureHandler(myAuthenctiationFailureHandler) // 自定义登录失败处理
                .successHandler(myAuthenctiationSuccessHandler) // 自定义登录成功处理
                .and()
                .authorizeRequests()  //定义哪些url需要保护,哪些url不需要保护
                .anyRequest().authenticated()
                .and()
                .sessionManagement().maximumSessions(1)
                .and()
                .and()
                .logout()
                .logoutUrl("/logout")
                .and()
                .formLogin()
                .loginPage("/login.html")  //定义当需要用户登录时候,转到的登录页面
                .loginProcessingUrl("/meureka/login")  // 自定义的登录接口
                .permitAll()
                .defaultSuccessUrl("/index.html").permitAll()
                .and()
                .logout()
                .permitAll()
                // 自动登录
                .and().rememberMe();
        http.csrf().disable();
        //解决中文乱码问题
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        filter.setForceEncoding(true);
        http.addFilterBefore(filter,CsrfFilter.class);
    }
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("admin")
            .password("12345678")
            .roles("USER");
        //在内存中创建了一个用户,该用户的名称为user,密码为password,用户角色为USER
    }
}

在这里我使用了spring-security自定义处理器 来处理登录失败和登陆成功的逻辑,方便前台ajax调用做相关处理业务

登录界面可以使用自己个性化的登录模板,

web.ignoring().antMatchers("/css/**");根据自己的项目进行配置 哪些不需要被拦截的url可以用这个来配置
配置登录账号密码  可以配置多个
auth.inMemoryAuthentication()
    .withUser("admin")
    .password("12345678")
    .roles("USER");

自定义配置项(根据自己项目配置)

第三步:自定义登录失败处理器  MyAuthenctiationFailureHandler

package com.xcloud.currency.config;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
@Component("myAuthenctiationFailureHandler")
public class MyAuthenctiationFailureHandler extends SimpleUrlAuthenticationFailureHandler {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
                                        AuthenticationException exception) throws IOException, ServletException {
        log.info("登录失败");
        JSONObject res = new JSONObject();
        res.put("success",false);
        res.put("msg","登录失败,请检查账号密码是否正确");
        response.setStatus(500);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().append(res.toString());
    }
}

第四步:自定义登录成功处理器  MyAuthenctiationSuccessHandler

package com.xcloud.currency.config;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
@Component("MyAuthenctiationSuccessHandler")
public class MyAuthenctiationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
        log.info("登录成功");
        JSONObject res = new JSONObject();
        res.put("success",true);
        res.put("msg","登录成功");
        response.setStatus(200);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().append(res.toString());
    }
}

登录页面上调用(普通表单形式)

ajax调用

function login() {
        var username = $("#username").val();
        var password = $("#password").val();
        if (username == "" || password == "") {
            layer.msg('用户名或密码不能为空', {icon: 2});
            return;
        }
        $.ajax({
            type: "POST",
            url: "meureka/login",
            data: {
                "username": username,
                "password": password
            },
            success: function (e) {
                layer.msg(e.msg, {icon: 1});
                setTimeout(function () {
                    location.href = 'index.html';
                }, 1500);
            },
            error: function (e) {
                console.log(e.responseText);
                layer.msg(JSON.parse(e.responseText).msg, {icon: 2});
            }
        });
    }

 

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Spring Security 实现手机验证码登录的完整流程如下: 1. 添加相关依赖 首先,需要在项目中添加 Spring Security 和 Spring Boot Starter Web 的依赖。 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> ``` 2. 配置 Spring Security 在 Spring Security 的配置类中,需要进行以下配置: - 配置忽略静态资源 - 配置登录页面和登录处理接口 - 配置登录成功后的跳转页面 - 配置用户认证和授权方式 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CustomUserDetailsService customUserDetailsService; @Autowired private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler; @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/login", "/login/sendCode").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .loginProcessingUrl("/login/authenticate") .successHandler(customAuthenticationSuccessHandler) .permitAll() .and() .logout() .permitAll() .and() .csrf() .disable(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(customUserDetailsService); } } ``` 3. 自定义用户认证和授权 需要实现 `UserDetailsService` 接口,根据手机号码查询用户信息,然后实现 `UserDetails` 接口返回用户信息。 ```java @Service public class CustomUserDetailsService implements UserDetailsService { @Autowired private UserRepository userRepository; @Override public UserDetails loadUserByUsername(String mobile) throws UsernameNotFoundException { User user = userRepository.findByMobile(mobile); if (user == null) { throw new UsernameNotFoundException("用户不存在"); } return new CustomUserDetails(user); } } ``` 实现 `UserDetails` 接口,返回用户信息。 ```java public class CustomUserDetails implements UserDetails { private User user; public CustomUserDetails(User user) { this.user = user; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return Collections.emptyList(); } @Override public String getPassword() { return user.getPassword(); } @Override public String getUsername() { return user.getMobile(); } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } } ``` 4. 实现发送验证码和校验验证码 在登录页面中,需要添加一个发送验证码的按钮,点击后通过 Ajax 请求发送验证码到用户手机上。 ```javascript function sendCode() { $.ajax({ type: 'post', url: '/login/sendCode', data: {mobile: $('#mobile').val()}, success: function(result) { if (result.code === 0) { alert('验证码发送成功'); } else { alert(result.message); } }, error: function() { alert('系统错误'); } }); } ``` 服务端接收到请求后,生成一个 6 位数的随机数作为验证码,并保存到 Redis 中,设置过期时间为 5 分钟。 ```java public class SmsCodeSender { private static final String SMS_CODE_PREFIX = "sms_code_"; public void send(String mobile) { String code = RandomStringUtils.randomNumeric(6); System.out.println("给手机号 " + mobile + " 发送验证码 " + code); RedisUtils.set(SMS_CODE_PREFIX + mobile, code, 5, TimeUnit.MINUTES); } } ``` 在登录处理接口中,需要校验用户输入的验证码是否与 Redis 中保存的验证码一致。 ```java @Controller public class LoginController { @Autowired private SmsCodeSender smsCodeSender; @PostMapping("/login/sendCode") @ResponseBody public Result sendCode(String mobile) { smsCodeSender.send(mobile); return Result.success(); } @PostMapping("/login/authenticate") public String login(String mobile, String code, HttpServletRequest request) { String smsCode = RedisUtils.get(SmsCodeSender.SMS_CODE_PREFIX + mobile); if (StringUtils.isBlank(smsCode)) { throw new BadCredentialsException("验证码已过期,请重新发送"); } if (!smsCode.equals(code)) { throw new BadCredentialsException("验证码不正确"); } UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(mobile, null); Authentication authentication = AuthenticationManagerBuilderUtils.getAuthenticationManager().authenticate(token); SecurityContextHolder.getContext().setAuthentication(authentication); return "redirect:/index"; } @GetMapping("/login") public String loginPage() { return "login"; } } ``` 5. 自定义登录成功处理器 在登录成功后,需要跳转到指定页面并显示用户信息。 ```java @Component public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { response.sendRedirect("/index"); } } ``` 6. 完成 至此,Spring Security 实现手机验证码登录的完整流程就完成了。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值