数据库密码字段

注入SpringSecurity注意:(配置启动类,避免循环依赖)
@SpringBootApplication @EnableGlobalMethodSecurity(securedEnabled = true)//开启security扫描权限注释 public class AppManageApplication { public static void main(String[] args) { SpringApplication.run(AppManageApplication.class, args); } @Bean //加密 PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
使用加密方法在注册时将用户密码存储在数据库中
passwordEncoder.encode(password)//获得密文
创建TokenWebSecurityConfig,security配置类
package com.zax.appmanage.config; import com.alibaba.druid.util.StringUtils; import com.zax.appmanage.entity.User; import com.zax.appmanage.security.VerificationCodeFilter; import com.zax.appmanage.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 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.WebSecurityConfigurerAdapter; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl; import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.stereotype.Component; import javax.sql.DataSource; import java.util.List; /** * TODO. * * @author meizhaowei * @since 2021/7/28 */ @Configuration public class TokenWebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired///注入数据源 private DataSource dataSource; @Autowired///用户名验证 @Qualifier("customUserDetailsService") UserDetailsService userDetailsService; @Autowired///自定义验证码过滤器 private VerificationCodeFilter verificationCodeFilter; @Bean ///密码验证过滤器 public AuthenticationProvider authenticationProvider() { return new MyAuthenticationProvider(); } @Autowired///验证过程 public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); auth.authenticationProvider(authenticationProvider()); } @Bean///配置操作数据库类别 public PersistentTokenRepository persistentTokenRepository(){ JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl(); jdbcTokenRepository.setDataSource(this.dataSource); // jdbcTokenRepository.setCreateTableOnStartup(true);///启动时创建手表 return jdbcTokenRepository; } @Override protected void configure(HttpSecurity http) throws Exception { ///验证验证码功能,将验证码过滤器添加到帐户密码过滤器前 http.addFilterBefore(verificationCodeFilter, UsernamePasswordAuthenticationFilter.class); //退出功能 http.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")) .logoutSuccessUrl("/login").permitAll(); //权限错误403跳转页面 http.exceptionHandling().accessDeniedPage("/unauth"); //【注意事项】放行资源要放在前面,认证放在后面 http.authorizeRequests() ///不需要认证的是static静态资源,以及/index请求 // .antMatchers() // .antMatchers("/hello")hasAuthority("admin")//拥有admin权限的用户才能访问此页面
.mvcMatchers("/favicon.ico","/login","/unauth","/verifyCode"
,"/images/**","/fonts/**","/css/**","/js/**",
"/static/**","/doRegis","/email","/newUser","/yz","/getuserName","/yzPassword","/yzPassword1").permitAll() //放行loginHtml请求
.anyRequest().authenticated()//代表其他请求需要认证
.and()
.formLogin()//表示其他需要认证的请求通过表单认证
//loginPage 一旦你自定义了这个登录页面,那你必须要明确告诉SpringSecurity日后哪个url处理你的登录请求
.loginPage("/login")//用来指定自定义登录界面,不使用SpringSecurity默认登录界面 注意:一旦自定义登录页面,必须指定登录url
//loginProcessingUrl 这个doLogin请求本身是没有的,因为我们只需要明确告诉SpringSecurity,日后只要前端发起的是一个doLogin这样的请求,
//那SpringSecurity应该把你username和password给捕获到
.loginProcessingUrl("/doLogin")//指定处理登录的请求url
.usernameParameter("userName") //指定登录界面用户名文本框的name值,如果没有指定,默认属性名必须为username
.passwordParameter("password")//指定登录界面密码密码框的name值,如果没有指定,默认属性名必须为password
// .successForwardUrl("/index")//认证成功 forward 跳转路径
.defaultSuccessUrl("/")//认证成功 之后跳转,重定向 redirect 跳转后,地址会发生改变 根据上一保存请求进行成功跳转
//配置自动登录操作
.and().rememberMe().tokenRepository(persistentTokenRepository()).userDetailsService(userDetailsService)
.tokenValiditySeconds(20000)//设置有效时长,单位秒
.and().csrf().disable(); //禁止csrf 跨站请求保护
}
}
再创建CustomUserDetailsService,用户名验证类
package com.zax.appmanage.config;
import com.zax.appmanage.entity.User;
import com.zax.appmanage.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Created by fjc on 2018/4/22.
*/
@Service("customUserDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private IUserService userService;
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
//通过用户输入的用户名查找数据库获取到user
User user = userService.selectAllByUserName(userName);
if(user==null){
System.out.println("User not found");
throw new UsernameNotFoundException("Username not found");
}
//传入三个参数分别是,用户名,密码,和用户权限
List<GrantedAuthority> auths =
AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_"+user.getUserType());
return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassword(),
auths);
}
}
将密码校验和权限校验交给MyAuthenticationProvider来实现
package com.zax.appmanage.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.Collection;
@Component//自定义密码验证
public class MyAuthenticationProvider implements AuthenticationProvider{
@Autowired //加密
private PasswordEncoder passwordEncoder;
@Autowired //用户名验证业务
private CustomUserDetailsService userService;
/**
* 自定义验证方式
*/
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
//获取用户输入的用户名和密码
String username = authentication.getName();
String password = (String) authentication.getCredentials();
//通过获取的用户名,得到userDetails对象
UserDetails user = userService.loadUserByUsername(username);
//加密过程在这里体现,明文,密文
if (!passwordEncoder.matches(password,user.getPassword())) {
throw new DisabledException("Wrong password.");
}
Collection<? extends GrantedAuthority> authorities = user.getAuthorities();
return new UsernamePasswordAuthenticationToken(user, password, authorities);
}
@Override
public boolean supports(Class<?> arg0) {
return true;
}
}
然后再security配置类中配置,就实现了加密验证和自动登录的功能。