springsecurity utils和config
时间: 2023-07-17 10:55:27 浏览: 199
Spring Security是一个用于身份验证和授权的框架,它提供了一系列的工具类和配置类来简化安全相关的操作。
其中,Spring Security Utils提供了一些帮助开发人员实现安全操作的工具类,比如密码加密、角色授权、用户认证等等。这些工具类可以使开发人员更加便捷地实现安全相关的功能。
而Spring Security Config则提供了一些配置类来帮助开发人员配置Spring Security。这些配置类可以配置Spring Security的认证方式、授权规则、安全拦截等等。通过使用这些配置类,开发人员可以更加灵活地配置Spring Security,以满足业务需求。
相关问题
springsecurity 实现手机验证码登录完整流程
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 实现手机验证码登录的完整流程就完成了。
Caused by: java.lang.NullPointerException: null at com.tushu.common.utils.SpringUtil.getBean(SpringUtil.java:35) ~[classes/:na] at com.tushu.service.impl.UserAdminServiceImpl.getCacheService(UserAdminServiceImpl.java:276) ~[classes/:na] at com.tushu.service.impl.UserAdminServiceImpl.getAdminByUsername(UserAdminServiceImpl.java:61) ~[classes/:na] at com.tushu.service.impl.UserAdminServiceImpl.loadUserByUsername(UserAdminServiceImpl.java:266) ~[classes/:na] at com.tushu.config.tuSecurityConfig.lambda$userDetailsService$0(tuSecurityConfig.java:30) ~[classes/:na] at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:93) ~[spring-security-core-5.5.3.jar:5.5.3] ... 68 common frames omitted
这个异常是由于Java代码中的一个空指针引起的,具体是在SpringUtil类的第35行,该行代码尝试获取一个bean,但是该bean为null,因此导致了空指针异常。这个异常通常是由于代码没有正确的初始化或者设置bean,或者bean的依赖关系出现了问题。建议检查SpringUtil类的代码,以及与该类相关的bean的设置和依赖关系。
阅读全文