采用springboot+springsecurity
用户实体类
public class T_user implements UserDetails {
private String username;
private String password;
// ... 省略get,set 方法
@Override
public String toString() {
return this.username;
}
@Override
public int hashCode() {
return username.hashCode();
}
@Override
public boolean equals(Object obj) {
return this.toString().equals(obj.toString());
}
// 权限
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> grantedAuthority = new ArrayList<> ();
if (roles != null && roles.size() > 0) {
for (T_role role : roles) {
grantedAuthority.add(new SimpleGrantedAuthority(role.getName()));
}
}
return grantedAuthority;
}
// 账号是否过期
@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
// 账号是否锁定
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
// 密码是否过期
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
// 账号是否可用
@Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return true;
}
}
登录认证实现类
@Service
public class UserServiceImpl implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Autowired
private SessionRegistry sessionRegistry;
//@Autowired
//private PasswordEncoder passwordEncoder;
@Autowired
private MD5PasswordEncoder md5PasswordEncoder;
/**
* 重写springSecurity类方法
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 通过用户名称获取对象
T_user user = userMapper.findByUserName(username);
if (user != null) {
// 因为角色的添加已经在用户实体类中加入了,所以查询到用户不为空,直接返回用户对象就可以了
// 123 模拟加密盐
user.setPassword(md5PasswordEncoder.encode(user.getPassword()+"123"));
return user;
} else {
throw new UsernameNotFoundException("admin: " + username + " 不存在!");
}
}
}
spring security配置文件
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled =true) // 启用授权注解
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
/** 获取数据库中信息存到User对象中 */
@Bean
public UserDetailsService userService(){ //注册userService 的bean
return new UserServiceImpl();
}
/**加密密码*/
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**MD5加密密码*/
@Bean
PasswordEncoder md5PasswordEncoder() {
return new MD5PasswordEncoder();
}
/** 放行静态资源 */
@Override
public void configure(WebSecurity web) throws Exception {
//解决静态资源被拦截的问题
web.ignoring().antMatchers("/css/**");
web.ignoring().antMatchers("/js/**");
web.ignoring().antMatchers("/images/**");
web.ignoring().antMatchers("/login/**");
//解决服务注册url被拦截的问题
web.ignoring().antMatchers("/resources/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// 登录
http.formLogin().loginPage("/toLogin").loginProcessingUrl("/doLogin")
.defaultSuccessUrl("/index")
.failureUrl("/toLogin?error=true");
//解决非thymeleaf的form表单提交被拦截问题
http.csrf().disable();
http
.authorizeRequests()
.antMatchers("/toLogin")
.permitAll()
.anyRequest()
.authenticated()
;
//session管理
//session失效后跳转到登录页面
http.sessionManagement().invalidSessionUrl("/toLogin");
//单用户登录,如果有一个登录了,同一个用户在其他地方登录将前一个剔除下线
//http.sessionManagement().maximumSessions(1).expiredSessionStrategy(expiredSessionStrategy());
//单用户登录,如果有一个登录了,同一个用户在其他地方不能登录
http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true);
//退出删除cookie
http.logout()
.permitAll()
.logoutUrl("/logout") //执行注销的url
.invalidateHttpSession(true) // 指定是否在注销时让httpSession无效
.deleteCookies("JESSIONID") // 清除cookie
.logoutSuccessUrl("/toLogin"); // 注销成功后跳转的url
super.configure(http);
//解决中文乱码问题
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceEncoding(true);
//http.addFilterBefore(filter,CsrfFilter.class);
http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);
}
/**
* 认证器
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 自定义加密
auth.userDetailsService(userService()).passwordEncoder(md5PasswordEncoder());
}
}
自定义的MD5加密类
这里的“123”对应UserService实现类中的123,模拟加密盐
MD5Utils是我的加密类
@Component
public class MD5PasswordEncoder implements PasswordEncoder {
/**
* 加密
*/
@Override
public String encode(CharSequence rawPassword) {
return MD5Utils.encryptPassword(rawPassword.toString());
}
/**
* 密码匹配器
* rawPassword 用户前端输入的密码
* encodedPassword 数据库中待匹配的密码
*/
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return encodedPassword.equals(MD5Utils.encryptPassword(rawPassword.toString()+"123"));
}
}
controller层
@Controller
public class UserController {
/**
* ROLE_USER 是角色名称
*/
@PreAuthorize("hasRole('ROLE_USER')")
@RequestMapping("/update")
@ResponseBody
public String update() {
System.out.println("这是修改请求");
return "update";
}
}